Data Exploration and Wrangling
The first step in performing any data analysis is to explore the data.
For example, we might want to better understand the variables included in the data, as we may learn about important details about the data that we should keep in mind as we try to predict our outcome variable.
First, let’s just get a general sense of our data. We can do that using the glimpse() function of the dplyr package (it is also in the tibble package).
We will also use the %>% pipe, which can be used to define the input for later sequential steps.
This will make more sense when we have multiple sequential steps using the same data object.
To use the pipe notation we need to install and load dplyr as well.
For example, here we start with pm data object and “pipe” the object into as input into the glimpse() function. The output is is an overview of what is in the pm object such as the number of rows and columns, all the column names, the data types for each column and the first view values in each column. The output below is scrollable so you can see everything from the glimpse() function.
Rows: 876
Columns: 50
$ id <dbl> 1003.001, 1027.000, 1033.100, 1049.100, 1…
$ value <dbl> 9.597647, 10.800000, 11.212174, 11.659091…
$ fips <dbl> 1003, 1027, 1033, 1049, 1055, 1069, 1073,…
$ lat <dbl> 30.49800, 33.28126, 34.75878, 34.28763, 3…
$ lon <dbl> -87.88141, -85.80218, -87.65056, -85.9683…
$ state <chr> "Alabama", "Alabama", "Alabama", "Alabama…
$ county <chr> "Baldwin", "Clay", "Colbert", "DeKalb", "…
$ city <chr> "Fairhope", "Ashland", "Muscle Shoals", "…
$ CMAQ <dbl> 8.098836, 9.766208, 9.402679, 8.534772, 9…
$ zcta <dbl> 36532, 36251, 35660, 35962, 35901, 36303,…
$ zcta_area <dbl> 190980522, 374132430, 16716984, 203836235…
$ zcta_pop <dbl> 27829, 5103, 9042, 8300, 20045, 30217, 90…
$ imp_a500 <dbl> 0.01730104, 1.96972318, 19.17301038, 5.78…
$ imp_a1000 <dbl> 1.4096021, 0.8531574, 11.1448962, 3.86764…
$ imp_a5000 <dbl> 3.3360118, 0.9851479, 15.1786154, 1.23114…
$ imp_a10000 <dbl> 1.9879187, 0.5208189, 9.7253870, 1.031646…
$ imp_a15000 <dbl> 1.4386207, 0.3359198, 5.2472094, 0.973044…
$ county_area <dbl> 4117521611, 1564252280, 1534877333, 20126…
$ county_pop <dbl> 182265, 13932, 54428, 71109, 104430, 1015…
$ log_dist_to_prisec <dbl> 4.648181, 7.219907, 5.760131, 3.721489, 5…
$ log_pri_length_5000 <dbl> 8.517193, 8.517193, 8.517193, 8.517193, 9…
$ log_pri_length_10000 <dbl> 9.210340, 9.210340, 9.274303, 10.409411, …
$ log_pri_length_15000 <dbl> 9.630228, 9.615805, 9.658899, 11.173626, …
$ log_pri_length_25000 <dbl> 11.32735, 10.12663, 10.15769, 11.90959, 1…
$ log_prisec_length_500 <dbl> 7.295356, 6.214608, 8.611945, 7.310155, 8…
$ log_prisec_length_1000 <dbl> 8.195119, 7.600902, 9.735569, 8.585843, 9…
$ log_prisec_length_5000 <dbl> 10.815042, 10.170878, 11.770407, 10.21420…
$ log_prisec_length_10000 <dbl> 11.88680, 11.40554, 12.84066, 11.50894, 1…
$ log_prisec_length_15000 <dbl> 12.205723, 12.042963, 13.282656, 12.35366…
$ log_prisec_length_25000 <dbl> 13.41395, 12.79980, 13.79973, 13.55979, 1…
$ log_nei_2008_pm25_sum_10000 <dbl> 0.318035438, 3.218632928, 6.573127301, 0.…
$ log_nei_2008_pm25_sum_15000 <dbl> 1.967358961, 3.218632928, 6.581917457, 3.…
$ log_nei_2008_pm25_sum_25000 <dbl> 5.067308, 3.218633, 6.875900, 4.887665, 4…
$ log_nei_2008_pm10_sum_10000 <dbl> 1.35588511, 3.31111648, 6.69187313, 0.000…
$ log_nei_2008_pm10_sum_15000 <dbl> 2.26783411, 3.31111648, 6.70127741, 3.350…
$ log_nei_2008_pm10_sum_25000 <dbl> 5.628728, 3.311116, 7.148858, 5.171920, 4…
$ popdens_county <dbl> 44.265706, 8.906492, 35.460814, 35.330814…
$ popdens_zcta <dbl> 145.716431, 13.639555, 540.887040, 40.718…
$ nohs <dbl> 3.3, 11.6, 7.3, 14.3, 4.3, 5.8, 7.1, 2.7,…
$ somehs <dbl> 4.9, 19.1, 15.8, 16.7, 13.3, 11.6, 17.1, …
$ hs <dbl> 25.1, 33.9, 30.6, 35.0, 27.8, 29.8, 37.2,…
$ somecollege <dbl> 19.7, 18.8, 20.9, 14.9, 29.2, 21.4, 23.5,…
$ associate <dbl> 8.2, 8.0, 7.6, 5.5, 10.1, 7.9, 7.3, 8.0, …
$ bachelor <dbl> 25.3, 5.5, 12.7, 7.9, 10.0, 13.7, 5.9, 17…
$ grad <dbl> 13.5, 3.1, 5.1, 5.8, 5.4, 9.8, 2.0, 8.7, …
$ pov <dbl> 6.1, 19.5, 19.0, 13.8, 8.8, 15.6, 25.5, 7…
$ hs_orless <dbl> 33.3, 64.6, 53.7, 66.0, 45.4, 47.2, 61.4,…
$ urc2013 <dbl> 4, 6, 4, 6, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ urc2006 <dbl> 5, 6, 4, 5, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ aod <dbl> 37.36364, 34.81818, 36.00000, 33.08333, 4…
We can see that there are 876 monitors (rows) and that we have 50 total variables (columns) - one of which is the outcome variable. In this case, the outcome variable is called value.
Notice that some of the variables that we would think of as factors (or categorical data) are currently of class character as indicated by the <chr> just to the right of the column names/variable names in the glimpse() output. This means that the variable values are character strings, such as words or phrases.
The other variables are of class <dbl>, which stands for double precision which indicates that the are numeric and that they have decimal values. In contrast, one could have integer values which would not allow for decimal numbers. Here is a link for more information on double precision numeric values.
Another common data class is factor which is abbreviated like this: <fct>. A factor is something that has unique levels but there is no appreciable order to the levels. For example we can have a numeric value that is just an id that we want to be interpreted as just a unique level and not as the number that it would typically indicate. This would be useful for several of our variables:
- the monitor ID (
id)
- the Federal Information Processing Standard number for the county where the monitor was located (
fips)
- the zip code tabulation area (
zcta)
None of the values actually have any real numeric meaning, so we want to make sure that R does not interpret them as if they do.
So let’s convert these variables into factors. We can do this using the across() function of the dplyr package and the as.factor() base function. The across() function has two main arguments: (i) the columns you want to operate on and (ii) the function or list of functions to apply to each column.
In this case, we are also using the magrittr assignment pipe or double pipe that looks like this %<>% of the magrittr package. This allows us use the pm data as input, but also reassigns the output to the same data object name.
Rows: 876
Columns: 50
$ id <fct> 1003.001, 1027.0001, 1033.1002, 1049.1003…
$ value <dbl> 9.597647, 10.800000, 11.212174, 11.659091…
$ fips <fct> 1003, 1027, 1033, 1049, 1055, 1069, 1073,…
$ lat <dbl> 30.49800, 33.28126, 34.75878, 34.28763, 3…
$ lon <dbl> -87.88141, -85.80218, -87.65056, -85.9683…
$ state <chr> "Alabama", "Alabama", "Alabama", "Alabama…
$ county <chr> "Baldwin", "Clay", "Colbert", "DeKalb", "…
$ city <chr> "Fairhope", "Ashland", "Muscle Shoals", "…
$ CMAQ <dbl> 8.098836, 9.766208, 9.402679, 8.534772, 9…
$ zcta <fct> 36532, 36251, 35660, 35962, 35901, 36303,…
$ zcta_area <dbl> 190980522, 374132430, 16716984, 203836235…
$ zcta_pop <dbl> 27829, 5103, 9042, 8300, 20045, 30217, 90…
$ imp_a500 <dbl> 0.01730104, 1.96972318, 19.17301038, 5.78…
$ imp_a1000 <dbl> 1.4096021, 0.8531574, 11.1448962, 3.86764…
$ imp_a5000 <dbl> 3.3360118, 0.9851479, 15.1786154, 1.23114…
$ imp_a10000 <dbl> 1.9879187, 0.5208189, 9.7253870, 1.031646…
$ imp_a15000 <dbl> 1.4386207, 0.3359198, 5.2472094, 0.973044…
$ county_area <dbl> 4117521611, 1564252280, 1534877333, 20126…
$ county_pop <dbl> 182265, 13932, 54428, 71109, 104430, 1015…
$ log_dist_to_prisec <dbl> 4.648181, 7.219907, 5.760131, 3.721489, 5…
$ log_pri_length_5000 <dbl> 8.517193, 8.517193, 8.517193, 8.517193, 9…
$ log_pri_length_10000 <dbl> 9.210340, 9.210340, 9.274303, 10.409411, …
$ log_pri_length_15000 <dbl> 9.630228, 9.615805, 9.658899, 11.173626, …
$ log_pri_length_25000 <dbl> 11.32735, 10.12663, 10.15769, 11.90959, 1…
$ log_prisec_length_500 <dbl> 7.295356, 6.214608, 8.611945, 7.310155, 8…
$ log_prisec_length_1000 <dbl> 8.195119, 7.600902, 9.735569, 8.585843, 9…
$ log_prisec_length_5000 <dbl> 10.815042, 10.170878, 11.770407, 10.21420…
$ log_prisec_length_10000 <dbl> 11.88680, 11.40554, 12.84066, 11.50894, 1…
$ log_prisec_length_15000 <dbl> 12.205723, 12.042963, 13.282656, 12.35366…
$ log_prisec_length_25000 <dbl> 13.41395, 12.79980, 13.79973, 13.55979, 1…
$ log_nei_2008_pm25_sum_10000 <dbl> 0.318035438, 3.218632928, 6.573127301, 0.…
$ log_nei_2008_pm25_sum_15000 <dbl> 1.967358961, 3.218632928, 6.581917457, 3.…
$ log_nei_2008_pm25_sum_25000 <dbl> 5.067308, 3.218633, 6.875900, 4.887665, 4…
$ log_nei_2008_pm10_sum_10000 <dbl> 1.35588511, 3.31111648, 6.69187313, 0.000…
$ log_nei_2008_pm10_sum_15000 <dbl> 2.26783411, 3.31111648, 6.70127741, 3.350…
$ log_nei_2008_pm10_sum_25000 <dbl> 5.628728, 3.311116, 7.148858, 5.171920, 4…
$ popdens_county <dbl> 44.265706, 8.906492, 35.460814, 35.330814…
$ popdens_zcta <dbl> 145.716431, 13.639555, 540.887040, 40.718…
$ nohs <dbl> 3.3, 11.6, 7.3, 14.3, 4.3, 5.8, 7.1, 2.7,…
$ somehs <dbl> 4.9, 19.1, 15.8, 16.7, 13.3, 11.6, 17.1, …
$ hs <dbl> 25.1, 33.9, 30.6, 35.0, 27.8, 29.8, 37.2,…
$ somecollege <dbl> 19.7, 18.8, 20.9, 14.9, 29.2, 21.4, 23.5,…
$ associate <dbl> 8.2, 8.0, 7.6, 5.5, 10.1, 7.9, 7.3, 8.0, …
$ bachelor <dbl> 25.3, 5.5, 12.7, 7.9, 10.0, 13.7, 5.9, 17…
$ grad <dbl> 13.5, 3.1, 5.1, 5.8, 5.4, 9.8, 2.0, 8.7, …
$ pov <dbl> 6.1, 19.5, 19.0, 13.8, 8.8, 15.6, 25.5, 7…
$ hs_orless <dbl> 33.3, 64.6, 53.7, 66.0, 45.4, 47.2, 61.4,…
$ urc2013 <dbl> 4, 6, 4, 6, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ urc2006 <dbl> 5, 6, 4, 5, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ aod <dbl> 37.36364, 34.81818, 36.00000, 33.08333, 4…
Great! Now we can see that these variables are now factors as indicated by <fct> after the variable name.
skim package
The skim() function of the skimr package is also really helpful for getting a general sense of your data. By design, it provides summary statistics about variables in the data set.
Notice how there is a column called n_missing about the number of values that are missing.
This is also indicated by the complete_rate variable (or missing/number of observations).
In our data set, it looks like our data do not contain any missing data.
Also notice how the function provides separate tables of summary statistics for each data type: character, factor and numeric.
Next, the n_unqiue column shows us the number of unique values for each of our columns. We can see that there are 49 states represented in the data.
We can see that for many variables there are many low values as the distribution shows two peaks, one near zero and another with a higher value.
This is true for the imp variables (measures of development), the nei variables (measures of emission sources) and the road density variables.
We can also see that the range of some of the variables is very large, in particular the area and population related variables.
Let’s take a look to see which states are included using the distinct() function of the dplyr package:
Scroll through the output:
It looks like “District of Columbia” is being included as a state. We can see that Alaska and Hawaii are not included in the data.
Let’s also take a look to see how many monitors there are in a few cities. We can use the filter() function of the dplyr package to do so. For example, let’s look at Albuquerque, New Mexico.
# A tibble: 2 x 50
id value fips lat lon state county city CMAQ zcta zcta_area
<fct> <dbl> <fct> <dbl> <dbl> <chr> <chr> <chr> <dbl> <fct> <dbl>
1 3500… 5.98 35001 35.1 -107. New … Berna… Albu… 10.1 87109 26199125
2 3500… 5.91 35001 35.1 -107. New … Berna… Albu… 10.1 87108 15224438
# … with 39 more variables: zcta_pop <dbl>, imp_a500 <dbl>, imp_a1000 <dbl>,
# imp_a5000 <dbl>, imp_a10000 <dbl>, imp_a15000 <dbl>, county_area <dbl>,
# county_pop <dbl>, log_dist_to_prisec <dbl>, log_pri_length_5000 <dbl>,
# log_pri_length_10000 <dbl>, log_pri_length_15000 <dbl>,
# log_pri_length_25000 <dbl>, log_prisec_length_500 <dbl>,
# log_prisec_length_1000 <dbl>, log_prisec_length_5000 <dbl>,
# log_prisec_length_10000 <dbl>, log_prisec_length_15000 <dbl>,
# log_prisec_length_25000 <dbl>, log_nei_2008_pm25_sum_10000 <dbl>,
# log_nei_2008_pm25_sum_15000 <dbl>, log_nei_2008_pm25_sum_25000 <dbl>,
# log_nei_2008_pm10_sum_10000 <dbl>, log_nei_2008_pm10_sum_15000 <dbl>,
# log_nei_2008_pm10_sum_25000 <dbl>, popdens_county <dbl>,
# popdens_zcta <dbl>, nohs <dbl>, somehs <dbl>, hs <dbl>, somecollege <dbl>,
# associate <dbl>, bachelor <dbl>, grad <dbl>, pov <dbl>, hs_orless <dbl>,
# urc2013 <dbl>, urc2006 <dbl>, aod <dbl>
We can see that there were only two monitors in the city of Albuquerque in 2006. Let’s compare this with Baltimore.
# A tibble: 5 x 50
id value fips lat lon state county city CMAQ zcta zcta_area
<fct> <dbl> <fct> <dbl> <dbl> <chr> <chr> <chr> <dbl> <fct> <dbl>
1 2451… 12.2 24510 39.3 -76.6 Mary… Balti… Balt… 10.9 21251 461424
2 2451… 12.5 24510 39.3 -76.7 Mary… Balti… Balt… 10.9 21215 17645223
3 2451… 12.8 24510 39.3 -76.5 Mary… Balti… Balt… 10.9 21224 24539976
4 2451… 14.3 24510 39.2 -76.6 Mary… Balti… Balt… 10.9 21226 25718732
5 2451… 13.3 24510 39.3 -76.6 Mary… Balti… Balt… 10.9 21202 4111039
# … with 39 more variables: zcta_pop <dbl>, imp_a500 <dbl>, imp_a1000 <dbl>,
# imp_a5000 <dbl>, imp_a10000 <dbl>, imp_a15000 <dbl>, county_area <dbl>,
# county_pop <dbl>, log_dist_to_prisec <dbl>, log_pri_length_5000 <dbl>,
# log_pri_length_10000 <dbl>, log_pri_length_15000 <dbl>,
# log_pri_length_25000 <dbl>, log_prisec_length_500 <dbl>,
# log_prisec_length_1000 <dbl>, log_prisec_length_5000 <dbl>,
# log_prisec_length_10000 <dbl>, log_prisec_length_15000 <dbl>,
# log_prisec_length_25000 <dbl>, log_nei_2008_pm25_sum_10000 <dbl>,
# log_nei_2008_pm25_sum_15000 <dbl>, log_nei_2008_pm25_sum_25000 <dbl>,
# log_nei_2008_pm10_sum_10000 <dbl>, log_nei_2008_pm10_sum_15000 <dbl>,
# log_nei_2008_pm10_sum_25000 <dbl>, popdens_county <dbl>,
# popdens_zcta <dbl>, nohs <dbl>, somehs <dbl>, hs <dbl>, somecollege <dbl>,
# associate <dbl>, bachelor <dbl>, grad <dbl>, pov <dbl>, hs_orless <dbl>,
# urc2013 <dbl>, urc2006 <dbl>, aod <dbl>
There were in contrast five monitors for the city of Baltimore, despite the fact that if we take a look at the land area and population of the counties for Blatimore City and Albuquerque, we can see that they had very similar land area and populations.
# A tibble: 5 x 2
county_area county_pop
<dbl> <dbl>
1 209643241 620961
2 209643241 620961
3 209643241 620961
4 209643241 620961
5 209643241 620961
# A tibble: 2 x 2
county_area county_pop
<dbl> <dbl>
1 3006530549 662564
2 3006530549 662564
In fact, the county containing Albuerque had a larger population. Thus the measurements for Albuquerque were not as thorough as they were for Baltimore.
This may be due to the fact that the monitor values were lower in Albuquerque. It is interesting to note here that the CMAQ values are quite similar for both cities.
Evaluate correlation
In prediction analyses, it is also useful to evaluate if any of the variables are correlated. Why should we care about this?
If we are using a linear regression to model our data then we might run into a problem called multicolinearity which can lead us to misinterpret what is really predictive of our outcome variable. This phenomenon occurs when the predictor variables actually predict one another. See this case study for a deeper explanation about this.
Another reason we should look out for correlation is that we don’t want to include redundant variables. This can add unnecessary noise to our algorithm causing a reduction in prediction accuracy and it can cause our algorithm to be unnecessarily slower. Finally, it can also make it difficult to interpret what variables are actually predictive.
Intuitively we can expect some of our variables to be correlated.
Let’s first take a look at all of our numeric variables with thecorrplot package: The corrplot package is another option to look at correlation among possible predictors, and particularly useful if we have many predictors.
First, we calculate the Pearson correlation coefficients between all features pairwise using the cor() function of the stats package (which is loaded automatically). Then we use the corrplot::corrplot() function.
The tl.cex = 0.5 argument controls the size of the text label.
We can also plot the absolute value of the Pearson correlation coefficients using the abs() function from base R and change the order of the columns.

There are several options for ordering the variables. See here for more options. Here we will use the “hclust” option for ordering by hierarchical clustering - which will order the variables by how similar they are to one another.
The cl.lim = c(0, 1) argument limits the color label to be between 0 and 1.
We can see that the development variables (imp) variables are correlated with each other as we might expect. We also see that the road density variables seem to be correlated with each other, and the emission variables seem to be correlated with each other.
Also notice that none of the predictors are highly correlated with our outcome variable (value).
We can take also take a closer look using the ggcorr() function and the ggpairs() function of the GGally package.
To select our variables of interest we can use the select() function with the contains() function of the tidyr package.
First let’s look at the imp/development variables. We can change the default color palette (palette = "RdBu") and add on correlation coefficients to the plot (label = TRUE).


Indeed, we can see that imp_a1000 and imp_a500 are highly correlated, as well as imp_a10000, imp_a15000.
Next, let’s take a look at the road density data:

We can see that many of the road density variables are highly correlated with one another, while others are less so.
Finally let’s look at the emission variables.


We would also expect the population density data might correlate with some of these variables. Let’s take a look.


Interesting, so these variables don’t appear to be highly correlated, therefore we might need variables from each of the categories to predict our monitor PM2.5 pollution values.
Because some variables in our data have extreme values, it might be good to take a log transformation. This can affect our estimates of correlation.


Indeed this increased the correlation, but variables from each of these categories may still prove to be useful for prediction.
Now that we have a sense of what our data are, we can get started with building a machine learning model to predict air pollution.
Data Visualization
Our main question for this case study was:
Can we predict annual average air pollution concentrations at the granularity of zip code regional levels using predictors such as data about population density, urbanization, road density, as well as, satellite pollution data and chemical modeling data?
Thus far, we have build a machine learning (ML) model to predict fine particulate matter air pollution levels based on our predictor variables (or features).
Now, let’s make a plot of our predicted outcome values (\(\hat{Y}\)) and actual outcome values \(Y\) we observed.
First, let’s start by making a plot of our monitors. To do this, we will use the following packages to create a map of the US:
sf - the simple features package helps to convert geographical coordinates into geometry variables which are useful for making 2D plots
maps - this package contains geographical outlines and plotting functions to create plots with maps
rnaturalearth- this allows for easy interaction with map data from Natural Earth which is a public domain map dataset
rgeos - this package interfaces with the Geometry Engine-Open Source (GEOS) which is also helpful for coordinate conversion
We will start with getting an outline of the US with the ne_countries() function of the rnaturalearth package which will return polygons of the countries in the Natural Earth dataset.
Rows: 241
Columns: 64
$ scalerank <int> 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 3, 1, 5, 3, 1, 1, 1, 1, 1, 1…
$ featurecla <chr> "Admin-0 country", "Admin-0 country", "Admin-0 country", "…
$ labelrank <dbl> 5, 3, 3, 6, 6, 6, 6, 4, 2, 6, 4, 4, 5, 6, 6, 2, 4, 5, 6, 2…
$ sovereignt <chr> "Netherlands", "Afghanistan", "Angola", "United Kingdom", …
$ sov_a3 <chr> "NL1", "AFG", "AGO", "GB1", "ALB", "FI1", "AND", "ARE", "A…
$ adm0_dif <dbl> 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0…
$ level <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
$ type <chr> "Country", "Sovereign country", "Sovereign country", "Depe…
$ admin <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ adm0_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ geou_dif <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ geounit <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ gu_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ su_dif <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ subunit <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ su_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ brk_diff <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ name <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ name_long <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ brk_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ brk_name <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ brk_group <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ abbrev <chr> "Aruba", "Afg.", "Ang.", "Ang.", "Alb.", "Aland", "And.", …
$ postal <chr> "AW", "AF", "AO", "AI", "AL", "AI", "AND", "AE", "AR", "AR…
$ formal_en <chr> "Aruba", "Islamic State of Afghanistan", "People's Republi…
$ formal_fr <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ note_adm0 <chr> "Neth.", NA, NA, "U.K.", NA, "Fin.", NA, NA, NA, NA, "U.S.…
$ note_brk <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Multiple clai…
$ name_sort <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ name_alt <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ mapcolor7 <dbl> 4, 5, 3, 6, 1, 4, 1, 2, 3, 3, 4, 4, 1, 7, 2, 1, 3, 1, 2, 3…
$ mapcolor8 <dbl> 2, 6, 2, 6, 4, 1, 4, 1, 1, 1, 5, 5, 2, 5, 2, 2, 1, 6, 2, 2…
$ mapcolor9 <dbl> 2, 8, 6, 6, 1, 4, 1, 3, 3, 2, 1, 1, 2, 9, 5, 2, 3, 5, 5, 1…
$ mapcolor13 <dbl> 9, 7, 1, 3, 6, 6, 8, 3, 13, 10, 1, NA, 7, 11, 5, 7, 4, 8, …
$ pop_est <dbl> 103065, 28400000, 12799293, 14436, 3639453, 27153, 83888, …
$ gdp_md_est <dbl> 2258.0, 22270.0, 110300.0, 108.9, 21810.0, 1563.0, 3660.0,…
$ pop_year <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ lastcensus <dbl> 2010, 1979, 1970, NA, 2001, NA, 1989, 2010, 2010, 2001, 20…
$ gdp_year <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ economy <chr> "6. Developing region", "7. Least developed region", "7. L…
$ income_grp <chr> "2. High income: nonOECD", "5. Low income", "3. Upper midd…
$ wikipedia <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ fips_10 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ iso_a2 <chr> "AW", "AF", "AO", "AI", "AL", "AX", "AD", "AE", "AR", "AM"…
$ iso_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALA", "AND", "ARE", "A…
$ iso_n3 <chr> "533", "004", "024", "660", "008", "248", "020", "784", "0…
$ un_a3 <chr> "533", "004", "024", "660", "008", "248", "020", "784", "0…
$ wb_a2 <chr> "AW", "AF", "AO", NA, "AL", NA, "AD", "AE", "AR", "AM", "A…
$ wb_a3 <chr> "ABW", "AFG", "AGO", NA, "ALB", NA, "ADO", "ARE", "ARG", "…
$ woe_id <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ adm0_a3_is <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALA", "AND", "ARE", "A…
$ adm0_a3_us <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ adm0_a3_un <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ adm0_a3_wb <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ continent <chr> "North America", "Asia", "Africa", "North America", "Europ…
$ region_un <chr> "Americas", "Asia", "Africa", "Americas", "Europe", "Europ…
$ subregion <chr> "Caribbean", "Southern Asia", "Middle Africa", "Caribbean"…
$ region_wb <chr> "Latin America & Caribbean", "South Asia", "Sub-Saharan Af…
$ name_len <dbl> 5, 11, 6, 8, 7, 5, 7, 20, 9, 7, 14, 10, 23, 22, 17, 9, 7, …
$ long_len <dbl> 5, 11, 6, 8, 7, 13, 7, 20, 9, 7, 14, 10, 27, 35, 19, 9, 7,…
$ abbrev_len <dbl> 5, 4, 4, 4, 4, 5, 4, 6, 4, 4, 9, 4, 7, 10, 6, 4, 5, 4, 4, …
$ tiny <dbl> 4, NA, NA, NA, NA, 5, 5, NA, NA, NA, 3, NA, NA, 2, 4, NA, …
$ homepart <dbl> NA, 1, 1, NA, 1, NA, 1, 1, 1, 1, NA, 1, NA, NA, 1, 1, 1, 1…
$ geometry <MULTIPOLYGON [°]> MULTIPOLYGON (((-69.89912 1..., MULTIPOLYGON …
Here you can see the data about the countries in the world. Notice the geometry variable. This is used to create the outlines that we want.
Now we can use the geom_sf() function of the ggplot2 package to create a visual of simple feature (the geometry coordinates found in the geometry variable).

So now we can see that we have outlines of all the countries in the world.
We want to limit this just to the coordinates for the US. We will do this based on the coordinates we found on Wikipedia. According to this link, these are the latitude and longitude bounds of the continental US:
- top = 49.3457868 # north lat
- left = -124.7844079 # west long
- right = -66.9513812 # east long
- bottom = 24.7433195 # south lat
Now we just have a plot that is mostly limited to the outline of the US.
Now we will use the geom_point() function of the ggplot package to add scatter plot on top of the map. We want to show where the monitors are located based on the latitude and longitude values in the data.
Nice!
Now let’s add county lines.
County graphical data is available from the maps package. The sf package which again is short for simple features creates a data frame about this graphical data so that we can work with it.
Simple feature collection with 3076 features and 1 field
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: -124.6813 ymin: 25.12993 xmax: -67.00742 ymax: 49.38323
CRS: EPSG:4326
First 10 features:
ID geom
1 alabama,autauga MULTIPOLYGON (((-86.50517 3...
2 alabama,baldwin MULTIPOLYGON (((-87.93757 3...
3 alabama,barbour MULTIPOLYGON (((-85.42801 3...
4 alabama,bibb MULTIPOLYGON (((-87.02083 3...
5 alabama,blount MULTIPOLYGON (((-86.9578 33...
6 alabama,bullock MULTIPOLYGON (((-85.66866 3...
7 alabama,butler MULTIPOLYGON (((-86.8604 31...
8 alabama,calhoun MULTIPOLYGON (((-85.74313 3...
9 alabama,chambers MULTIPOLYGON (((-85.59416 3...
10 alabama,cherokee MULTIPOLYGON (((-85.46812 3...
Now we will use this data within the geom_sf() function to add this to our plot. We will also add a title using the ggtitle() function, as well as remove axis ticks and titles using the theme() function of the ggplot2 package.
monitors <- ggplot(data = world) +
geom_sf(data = counties, fill = NA, color = gray(.5))+
coord_sf(xlim = c(-125, -66), ylim = c(24.5, 50),
expand = FALSE) +
geom_point(data = pm, aes(x = lon, y = lat), size = 2,
shape = 23, fill = "darkred") +
ggtitle("Monitor Locations") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
monitors

Great!
Now, let’s add a fill at the county-level for the true monitor values of air pollution.
First, we need to get the county map data that we just got and our air pollution data to have similarly formatted county names so that we can combine the datasets together.
We can see that in the county data the counties are listed after the state name and a comma. In addition they are all lower case.
Simple feature collection with 6 features and 1 field
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: -88.01778 ymin: 30.24071 xmax: -85.06131 ymax: 34.2686
CRS: EPSG:4326
ID geom
1 alabama,autauga MULTIPOLYGON (((-86.50517 3...
2 alabama,baldwin MULTIPOLYGON (((-87.93757 3...
3 alabama,barbour MULTIPOLYGON (((-85.42801 3...
4 alabama,bibb MULTIPOLYGON (((-87.02083 3...
5 alabama,blount MULTIPOLYGON (((-86.9578 33...
6 alabama,bullock MULTIPOLYGON (((-85.66866 3...
In contrast, our air pollution pm data shows counties as titles with the first letter as upper case.
[1] "Baldwin" "Clay" "Colbert" "DeKalb" "Etowah" "Houston"
We can use the separate() function of the tidyr package to separate the ID variable of our counties data into two variables based on the comma as a separator.
Simple feature collection with 6 features and 2 fields
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: -88.01778 ymin: 30.24071 xmax: -85.06131 ymax: 34.2686
CRS: EPSG:4326
state county geom
1 alabama autauga MULTIPOLYGON (((-86.50517 3...
2 alabama baldwin MULTIPOLYGON (((-87.93757 3...
3 alabama barbour MULTIPOLYGON (((-85.42801 3...
4 alabama bibb MULTIPOLYGON (((-87.02083 3...
5 alabama blount MULTIPOLYGON (((-86.9578 33...
6 alabama bullock MULTIPOLYGON (((-85.66866 3...
Now we just need to make these names in the new county variable of the counties data to be in title format. We can use the str_to_title() function of the stringr package to do this.
Great! Now the county information is the same for the counties and pm data.
We can use the inner_join() function of the dplyr package to join the datasets together based on the county variables in each. This function will keep all rows that are in both datasets.
Rows: 3,926
Columns: 52
$ state.x <chr> "alabama", "alabama", "alabama", "alabama…
$ county <chr> "Baldwin", "Bibb", "Bibb", "Butler", "But…
$ id <fct> 1003.001, 13021.0007, 13021.0012, 39017.0…
$ value <dbl> 9.597647, 12.253134, 12.233673, 13.918079…
$ fips <fct> 1003, 13021, 13021, 39017, 39017, 13059, …
$ lat <dbl> 30.49800, 32.77746, 32.80541, 39.49380, 3…
$ lon <dbl> -87.88141, -83.64110, -83.54352, -84.3543…
$ state.y <chr> "Alabama", "Georgia", "Georgia", "Ohio", …
$ city <chr> "In a city", "In a city", "In a city", "I…
$ CMAQ <dbl> 8.098836, 11.716801, 11.716801, 11.321991…
$ zcta <fct> 36532, 31206, 31020, 45044, 45015, 30605,…
$ zcta_area <dbl> 190980522, 72325015, 276913325, 98746815,…
$ zcta_pop <dbl> 27829, 29072, 2541, 52822, 12038, 39952, …
$ imp_a500 <dbl> 0.01730104, 35.64359862, 0.28200692, 27.4…
$ imp_a1000 <dbl> 1.4096021, 24.4824827, 0.2973616, 28.2887…
$ imp_a5000 <dbl> 3.3360118, 8.7317283, 2.4691097, 22.69740…
$ imp_a10000 <dbl> 1.9879187, 9.1999720, 1.9873487, 11.90155…
$ imp_a15000 <dbl> 1.4386207, 6.4619966, 3.6435089, 8.405292…
$ county_area <dbl> 4117521611, 646879637, 646879637, 1209668…
$ county_pop <dbl> 182265, 155547, 155547, 368130, 368130, 1…
$ log_dist_to_prisec <dbl> 4.648181, 7.635438, 7.576493, 5.959728, 5…
$ log_pri_length_5000 <dbl> 8.517193, 10.215058, 10.659655, 9.747731,…
$ log_pri_length_10000 <dbl> 9.210340, 12.116408, 11.653566, 10.734382…
$ log_pri_length_15000 <dbl> 9.630228, 12.591833, 12.313347, 11.172817…
$ log_pri_length_25000 <dbl> 11.32735, 13.12475, 13.02383, 12.14238, 1…
$ log_prisec_length_500 <dbl> 7.295356, 6.214608, 6.214608, 8.104926, 7…
$ log_prisec_length_1000 <dbl> 8.195119, 7.600902, 7.600902, 9.180109, 8…
$ log_prisec_length_5000 <dbl> 10.81504, 11.61283, 11.34202, 11.63677, 1…
$ log_prisec_length_10000 <dbl> 11.88680, 13.23991, 12.47152, 12.62117, 1…
$ log_prisec_length_15000 <dbl> 12.20572, 13.74532, 13.37704, 13.26170, 1…
$ log_prisec_length_25000 <dbl> 13.41395, 14.28483, 14.25295, 14.16745, 1…
$ log_nei_2008_pm25_sum_10000 <dbl> 0.3180354, 5.5380414, 0.1972941, 7.230784…
$ log_nei_2008_pm25_sum_15000 <dbl> 1.967359, 5.538041, 5.536822, 7.408732, 5…
$ log_nei_2008_pm25_sum_25000 <dbl> 5.067308, 5.986616, 5.986572, 7.538614, 7…
$ log_nei_2008_pm10_sum_10000 <dbl> 1.3558851, 5.6035407, 0.9849611, 7.278576…
$ log_nei_2008_pm10_sum_15000 <dbl> 2.2678341, 5.6035407, 5.5971561, 7.489928…
$ log_nei_2008_pm10_sum_25000 <dbl> 5.6287284, 6.0302900, 6.0347672, 7.633004…
$ popdens_county <dbl> 44.265706, 240.457407, 240.457407, 304.32…
$ popdens_zcta <dbl> 145.716431, 401.963277, 9.176156, 534.923…
$ nohs <dbl> 3.300, 8.700, 6.800, 1.300, 3.500, 3.800,…
$ somehs <dbl> 4.900, 24.700, 17.500, 3.300, 7.700, 6.80…
$ hs <dbl> 25.10, 32.60, 46.60, 33.40, 33.40, 17.80,…
$ somecollege <dbl> 19.7, 12.9, 18.7, 23.0, 23.2, 16.1, 18.8,…
$ associate <dbl> 8.200, 4.800, 5.000, 8.700, 8.100, 5.100,…
$ bachelor <dbl> 25.30, 8.90, 4.00, 22.20, 16.20, 25.40, 5…
$ grad <dbl> 13.50, 7.30, 1.30, 8.10, 7.90, 25.00, 3.1…
$ pov <dbl> 6.100, 38.800, 26.800, 0.900, 6.900, 12.1…
$ hs_orless <dbl> 33.30, 66.00, 70.90, 38.00, 44.60, 28.40,…
$ urc2013 <dbl> 4, 4, 4, 2, 2, 4, 6, 2, 4, 1, 1, 1, 3, 4,…
$ urc2006 <dbl> 5, 4, 4, 2, 2, 4, 6, 2, 4, 1, 1, 1, 3, 4,…
$ aod <dbl> 37.36364, 36.25000, 30.45455, 48.36364, 5…
$ geom <MULTIPOLYGON [°]> MULTIPOLYGON (((-87.93757 3.…
Nice! we can see that we have add a geom variable to the pm data.
Now we can use this to color the counties in our plot based on the value variable of our pm data, which you may recall is the actual monitor data for fine particulate air pollution at each monitor.
WE can do so using the scale_fill_gradientn() function of the ggplot2 package which creates color gradient based on a variable. In this case it is the variable that was specified as the fill in the aes function of the geom_sf() function. We specified that it would be the value variable of the pm data.
This scale_fill_gradientn() function also allows you to specify the colors, what to do about NA values (should they be a specific color or transparent) and the breaks, limits, labels and name/title on the legend for the color gradient.
truth <-ggplot(data = world) +
coord_sf(xlim = c(-125, -66), ylim = c(24.5, 50), expand = FALSE)+
geom_sf(data = map_data, aes(fill = value)) +
scale_fill_gradientn(colours=topo.colors(7), na.value = "transparent",
breaks=c(0,10,20),labels=c(0,10,20),
limits=c(0,23.5), name = "PM ug/m3") +
ggtitle("True PM 2.5 levels") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
truth
Nice!
Now let’s do the same with our predicted outcome values.
Let’s grab both the testing and training predicted outcome values so that we have as much data as possible.
First we need to fit our training data with our final model to be able to get the predictions for the monitors included in the training set. We did this using the last_fit() function, but the output of this makes it difficult to grab the predicted values for the training data, and it is also difficult to get the id variables for the testing data.
Thus we will use the parsnip fit() and predict() functions of the parsnip package to do this like so:
Question Opportunity
Why do we not need pre-processed data?
Click here to reveal the answer.
Since we are using a workflow, the data will be pre-processed when it is fit as well.
# A tibble: 584 x 5
.pred value fips county id
<dbl> <dbl> <fct> <chr> <fct>
1 10.0 9.60 1003 Baldwin 1003.001
2 11.0 10.8 1027 Clay 1027.0001
3 11.4 11.2 1033 Colbert 1033.1002
4 12.1 12.4 1055 Etowah 1055.001
5 10.7 10.5 1069 Houston 1069.0003
6 14.6 15.6 1073 Jefferson 1073.0023
7 12.1 12.4 1073 Jefferson 1073.1005
8 11.1 11.1 1073 Jefferson 1073.1009
9 13.9 14.6 1073 Jefferson 1073.2003
10 11.8 12.0 1073 Jefferson 1073.5002
# … with 574 more rows
# A tibble: 292 x 5
.pred value fips county id
<dbl> <dbl> <fct> <chr> <fct>
1 11.7 11.7 1049 DeKalb 1049.1003
2 12.6 13.1 1073 Jefferson 1073.101
3 12.2 12.2 1073 Jefferson 1073.2006
4 12.0 12.2 1089 Madison 1089.0014
5 11.6 11.4 1103 Morgan 1103.0011
6 12.3 12.2 1121 Talladega 1121.0002
7 10.7 10.9 4013 Maricopa 4013.4003
8 10.6 10.6 4021 Pinal 4021.0001
9 12.0 14.1 4023 Santa Cruz 4023.0004
10 7.81 5.83 4025 Yavapai 4025.2002
# … with 282 more rows
Now we can combine this data for the predictions for all monitors using the bind_rows() function of the dplyr package, which will essentially append the second dataset to the first.
# A tibble: 876 x 5
.pred value fips county id
<dbl> <dbl> <fct> <chr> <fct>
1 11.7 11.7 1049 DeKalb 1049.1003
2 12.6 13.1 1073 Jefferson 1073.101
3 12.2 12.2 1073 Jefferson 1073.2006
4 12.0 12.2 1089 Madison 1089.0014
5 11.6 11.4 1103 Morgan 1103.0011
6 12.3 12.2 1121 Talladega 1121.0002
7 10.7 10.9 4013 Maricopa 4013.4003
8 10.6 10.6 4021 Pinal 4021.0001
9 12.0 14.1 4023 Santa Cruz 4023.0004
10 7.81 5.83 4025 Yavapai 4025.2002
# … with 866 more rows
Great! as we can see there are 876 values like we would expect for all of the monitors. We can use the county variable to combine this with the counties data like we did with the pm data previously so that we can use the value variable as a color scheme for our map.
map_data <- inner_join(counties, all_pred, by = "county")
pred <- ggplot(data = world) +
coord_sf(xlim = c(-125, -66), ylim = c(24.5, 50),
expand = FALSE) +
geom_sf(data = map_data, aes(fill = .pred)) +
scale_fill_gradientn(colours=topo.colors(7), na.value = "transparent",
breaks=c(0,10,20),labels=c(0,10,20),
limits=c(0,23.5), name = "PM ug/m3") +
ggtitle("Predicted PM 2.5 levels")+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
pred

Now we will use the patchwork package to combine our last two plots. This allows us to combine plots using the + or the / . The + will place plots side by side and the / will place plots top to bottom.
Now let’s just combine the truth plot and the prediction plots together:

We can see that the predicted fine particle air pollution values in (ug/m3) are quite similar to the true values measured by the actual gravimetric monitors. We can also see that southern California has some large counties with worse pollution (as they are yellow and thus have much higher particulate matter levels).
Let’s add some text to our plot to explain it a bit more. We can do so using the plot_annotation() function of the patchwork package. The theme argument of this function takes the same theme information using the theme() function of the ggplot2 package as when creating ggplot2plots.

LS0tCnRpdGxlOiAiT3BlbiBDYXNlIFN0dWRpZXM6IFByZWRpY3RpbmcgQW5udWFsIEFpciBQb2xsdXRpb24iCmNzczogc3R5bGUuY3NzCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgc2VsZl9jb250YWluZWQ6IHllcwogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vCiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgd29yZF9kb2N1bWVudDoKICAgIHRvYzogeWVzCgotLS0KPHN0eWxlPgojVE9DIHsKICBiYWNrZ3JvdW5kOiB1cmwoImh0dHBzOi8vb3BlbmNhc2VzdHVkaWVzLmdpdGh1Yi5pby9pbWcvaWNvbi1iYWhpLnBuZyIpOwogIGJhY2tncm91bmQtc2l6ZTogY29udGFpbjsKICBwYWRkaW5nLXRvcDogMjQwcHggIWltcG9ydGFudDsKICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Owp9Cjwvc3R5bGU+Cgo8IS0tIE9wZW4gYWxsIGxpbmtzIGluIG5ldyB0YWItLT4gIAo8YmFzZSB0YXJnZXQ9Il9ibGFuayIvPiAKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGhlcmUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChpbmNsdWRlID0gVFJVRSwgY29tbWVudCA9IE5BLCBlY2hvID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBjYWNoZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLmFsaWduID0gImNlbnRlciIsIG91dC53aWR0aCA9ICc5MCUnKQpgYGAKCgojIyMjIHsub3V0bGluZSB9CmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI4MDAgcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCAibWFpbl9wbG90X21hcHMucG5nIikpCmBgYAoKIyMjIwoKIyMjIyB7LmRpc2NsYWltZXJfYmxvY2t9CgoqKkRpc2NsYWltZXIqKjogVGhlIHB1cnBvc2Ugb2YgdGhlIFtPcGVuIENhc2UgU3R1ZGllc10oaHR0cHM6Ly9vcGVuY2FzZXN0dWRpZXMuZ2l0aHViLmlvKXt0YXJnZXQ9Il9ibGFuayJ9IHByb2plY3QgaXMgKip0byBkZW1vbnN0cmF0ZSB0aGUgdXNlIG9mIHZhcmlvdXMgZGF0YSBzY2llbmNlIG1ldGhvZHMsIHRvb2xzLCBhbmQgc29mdHdhcmUgaW4gdGhlIGNvbnRleHQgb2YgbWVzc3ksIHJlYWwtd29ybGQgZGF0YSoqLiBBIGdpdmVuIGNhc2Ugc3R1ZHkgZG9lcyBub3QgY292ZXIgYWxsIGFzcGVjdHMgb2YgdGhlIHJlc2VhcmNoIHByb2Nlc3MsIGlzIG5vdCBjbGFpbWluZyB0byBiZSB0aGUgbW9zdCBhcHByb3ByaWF0ZSB3YXkgdG8gYW5hbHl6ZSBhIGdpdmVuIGRhdGEgc2V0LCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGluIHRoZSBjb250ZXh0IG9mIG1ha2luZyBwb2xpY3kgZGVjaXNpb25zIHdpdGhvdXQgZXh0ZXJuYWwgY29uc3VsdGF0aW9uIGZyb20gc2NpZW50aWZpYyBleHBlcnRzLiAKCiMjIyMKCiMjIyMgey5saWNlbnNlX2Jsb2NrfQoKVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBDcmVhdGl2ZSBDb21tb25zIEF0dHJpYnV0aW9uLU5vbkNvbW1lcmNpYWwgMy4wIFsoQ0MgQlktTkMgMy4wKV0oaHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LW5jLzMuMC91cy8pe3RhcmdldD0iX2JsYW5rIn0gVW5pdGVkIFN0YXRlcyBMaWNlbnNlLgoKIyMjIwoKIyMjIyB7LnJlZmVyZW5jZV9ibG9ja30KClRvIGNpdGUgdGhpcyBjYXNlIHN0dWR5IHBsZWFzZSB1c2U6CgpXcmlnaHQsIENhcnJpZSBhbmQgSmFnZXIsIExlYWggYW5kIFRhdWIsIE1hcmdhcmV0IGFuZCBIaWNrcywgU3RlcGhhbmllLiAoMjAyMCkuIFtodHRwczovL2dpdGh1Yi5jb20vL29wZW5jYXNlc3R1ZGllcy9vY3MtYnAtYWlyLXBvbGx1dGlvbl0oaHR0cHM6Ly9naXRodWIuY29tLy9vcGVuY2FzZXN0dWRpZXMvb2NzLWJwLWFpci1wb2xsdXRpb24vKS4gUHJlZGljdGluZyBBbm51YWwgQWlyIFBvbGx1dGlvbiAoVmVyc2lvbiB2MS4wLjApLgoKIyMjIwoKVG8gYWNjZXNzIHRoZSBHaXRIdWIgUmVwb3NpdG9yeSBmb3IgdGhpcyBjYXNlIHN0dWR5IHNlZSBoZXJlOiBodHRwczovL2dpdGh1Yi5jb20vb3BlbmNhc2VzdHVkaWVzL29jcy1icC1haXItcG9sbHV0aW9uLgoKVGhpcyBjYXNlIHN0dWR5IGlzIHBhcnQgb2YgYSBzZXJpZXMgb2YgcHVibGljIGhlYWx0aCBjYXNlIHN0dWRpZXMgZm9yIHRoZSBbQmxvb21iZXJnIEFtZXJpY2FuIEhlYWx0aCAgSW5pdGlhdGl2ZV0oaHR0cHM6Ly9hbWVyaWNhbmhlYWx0aC5qaHUuZWR1L29wZW4tY2FzZS1zdHVkaWVzKS4KCiMgKipNb3RpdmF0aW9uKioKKioqCkEgdmFyaWV0eSBvZiBkaWZmZXJlbnQgc291cmNlcyBjb250cmlidXRlIGRpZmZlcmVudCB0eXBlcyBvZiBwb2xsdXRhbnRzIHRvIHdoYXQgd2UgY2FsbCBhaXIgcG9sbHV0aW9uLiAKClNvbWUgc291cmNlcyBhcmUgbmF0dXJhbCB3aGlsZSBvdGhlcnMgYXJlIGFudGhyb3BvZ2VuaWMgKGh1bWFuIGRlcml2ZWQpOgoKPHAgYWxpZ249ImNlbnRlciI+CjxpbWcgd2lkdGg9IjYwMCIgc3JjPSJodHRwczovL3d3dy5ucHMuZ292L3N1YmplY3RzL2Fpci9pbWFnZXMvU291cmNlc19HcmFwaGljX0h1Z2UuanBnP21heHdpZHRoPTEyMDAmbWF4aGVpZ2h0PTEyMDAmYXV0b3JvdGF0ZT1mYWxzZSI+CjwvcD4KCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS91cmw/c2E9aSZ1cmw9aHR0cHMlM0ElMkYlMkZ3d3cubnBzLmdvdiUyRnN1YmplY3RzJTJGYWlyJTJGc291cmNlcy5odG0mcHNpZz1BT3ZWYXcydjdBVnhTRjhaU0FQRWhOdWRWdGJOJnVzdD0xNTg1NzcwOTY2MjE3MDAwJnNvdXJjZT1pbWFnZXMmY2Q9dmZlJnZlZD0wQ0FJUWpSeHFGd29UQ1BETjY2cV94ZWdDRlFBQUFBQWRBQUFBQUJBRCl7dGFyZ2V0PSJfYmxhbmsifQoKIyMjIE1ham9yIHR5cGVzIG9mIGFpciBwb2xsdXRhbnRzCgoxKSAqKkdhc2VvdXMqKiAtIENhcmJvbiBNb25veGlkZSAoQ08pLCBPem9uZSAoT34zfiksIE5pdHJvZ2VuIE94aWRlcyhOTywgTk9+Mn4pLCBTdWxwaGVyIERpb3hpZGUgKFNPfjJ+KQoyKSAqKlBhcnRpY3VsYXRlKiogLSBzbWFsbCBsaXF1aWRzIGFuZCBzb2xpZHMgc3VzcGVuZGVkIGluIHRoZSBhaXIgKGluY2x1ZGVzIGxlYWQtIGNhbiBpbmNsdWRlIGNlcnRhaW4gdHlwZXMgb2YgZHVzdCkKMykgKipEdXN0KiogLSBzbWFsbCBzb2xpZHMgKGxhcmdlciB0aGFuIHBhcnRpY3VsYXRlcykgdGhhdCBjYW4gYmUgc3VzcGVuZGVkIGluIHRoZSBhaXIgZm9yIHNvbWUgdGltZSBidXQgZXZlbnR1YWxseSBzZXR0bGUKNCkgKipCaW9sb2dpY2FsKiogLSBwb2xsZW4sIGJhY3RlcmlhLCB2aXJ1c2VzLCBtb2xkIHNwb3JlcwoKU2VlIFtoZXJlXShodHRwOi8vd3d3LnJlZGxvZ2Vudi5jb20vd29ya2VyLXNhZmV0eS9wYXJ0LTEtZHVzdC1hbmQtcGFydGljdWxhdGUtbWF0dGVyKSBmb3IgbW9yZSBkZXRhaWwgb24gdGhlIHR5cGVzIG9mIHBvbGx1dGFudHMgaW4gdGhlIGFpci4KCgojIyMgUGFydGljdWxhdGUgcG9sbHV0aW9uIAoKQWlyIHBvbGx1dGlvbiBwYXJ0aWN1bGF0ZXMgYXJlIGdlbmVyYWxseSBkZXNjcmliZWQgYnkgdGhlaXIgKipzaXplKiouCgpUaGVyZSBhcmUgMyBtYWpvciBjYXRlZ29yaWVzOgoKMSkgKipMYXJnZSBDb2Fyc2UqKiBQYXJ0aWN1bGF0ZSBNYXR0ZXIgLSBoYXMgZGlhbWV0ZXIgb2YgPjEwIG1pY3JvbWV0ZXJzICgxMCDCtW0pIAoKMikgKipDb2Fyc2UqKiBQYXJ0aWN1bGF0ZSBNYXR0ZXIgKGNhbGxlZCAqKlBNfjEwLTIuNX4qKikgLSBoYXMgZGlhbWV0ZXIgb2YgYmV0d2VlbiAyLjUgwrVtIGFuZCAxMCDCtW0KCjMpICoqRmluZSoqIFBhcnRpY3VsYXRlIE1hdHRlciAoY2FsbGVkICoqUE1+Mi41fioqKSAtIGhhcyBkaWFtZXRlciBvZiA8IDIuNSDCtW0gCgoqKlBNfjEwfioqIGluY2x1ZGVzIGFueSBwYXJ0aWN1bGF0ZSBtYXR0ZXIgPDEwIMK1bSAoYm90aCBjb2Fyc2UgYW5kIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyKQoKSGVyZSB5b3UgY2FuIHNlZSBob3cgdGhlc2Ugc2l6ZXMgY29tcGFyZSB3aXRoIGEgaHVtYW4gaGFpcjoKCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0gIjYwMCBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJwbTIuNV9zY2FsZV9ncmFwaGljLWNvbG9yXzIuanBnIikpCmBgYAoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL3d3dy5lcGEuZ292L3BtLXBvbGx1dGlvbi9wYXJ0aWN1bGF0ZS1tYXR0ZXItcG0tYmFzaWNzKXt0YXJnZXQ9Il9ibGFuayJ9Cgo8IS0tIDxwIGFsaWduPSJjZW50ZXIiPiAtLT4KPCEtLSAgIDxpbWcgd2lkdGg9IjUwMCIgc3JjPSJodHRwczovL3d3dy5zZW5zaXJpb24uY29tL2ltYWdlcy9zZW5zaXJpb24tc3BlY2lhbGlzdC1hcnRpY2xlLWZpZ3VyZS0xLWNkZDcwLmpwZyI+IC0tPgo8IS0tIDwvcD4gLS0+CgoKPHU+VGhlIGZvbGxvd2luZyBwbG90IGFuZCB0YWJsZSBzaG93IHRoZSByZWxhdGl2ZSBzaXplcyBvZiB0aGVzZSBkaWZmZXJlbnQgcG9sbHV0YW50cyBpbiBtaWNyb21ldGVycyAowrVtKTo8L3U+CgpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGg9ICI4MDAgcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCAicGFydGljdWxhdGUtc2l6ZS1jaGFydC5wbmciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BhcnRpY3VsYXRlcyl7dGFyZ2V0PSJfYmxhbmsifQoKCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0gIjgwMCBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJwYXJ0aWN1bGF0ZV90eXBlcy5qcGciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3LmZyb250aWVyc2luLm9yZy9hcnRpY2xlcy8xMC4zMzg5L2ZwdWJoLjIwMjAuMDAwMTQvZnVsbCl7dGFyZ2V0PSJfYmxhbmsifQoKCjx1PlRoaXMgdGFibGUgc2hvd3MgaG93IGRlZXBseSBzb21lIG9mIHRoZSBzbWFsbGVyIGZpbmUgcGFydGljbGVzIGNhbiBwZW5ldHJhdGUgd2l0aGluIHRoZSBodW1hbiBib2R5OjwvdT4KCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0gIjgwMCBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJzaXplcy5qcGciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3LmZyb250aWVyc2luLm9yZy9hcnRpY2xlcy8xMC4zMzg5L2ZwdWJoLjIwMjAuMDAwMTQvZnVsbCl7dGFyZ2V0PSJfYmxhbmsifQoKCiMjIyBOZWdhdGl2ZSBpbXBhY3Qgb2YgcGFydGljdWxhdGUgZXhwb3N1cmUgb24gaGVhbHRoIAoKRXhwb3N1cmUgdG8gYWlyIHBvbGx1dGlvbiBpcyBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIHJhdGVzIG9mIFttb3J0YWxpdHldKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcG1jL2FydGljbGVzL1BNQzU3ODMxODYvKXt0YXJnZXQ9Il9ibGFuayJ9IGluIG9sZGVyIGFkdWx0cyBhbmQgaXMga25vd24gdG8gYmUgYSByaXNrIGZhY3RvciBmb3IgbWFueSBkaXNlYXNlcyBhbmQgY29uZGl0aW9ucyBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvOgoKMSkgW0FzdGhtYV0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMjkyNDM5Mzcpe3RhcmdldD0iX2JsYW5rIn0gLSBmaW5lIHBhcnRpY2xlIGV4cG9zdXJlICgqKlBNfjIuNX4qKikgd2FzIGZvdW5kIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgcmF0ZXMgb2YgYXN0aG1hIGluIGNoaWxkcmVuCjIpIFtJbmZsYW1tYXRpb24gaW4gdHlwZSAxIGRpYWJldGVzXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8zMTQxOTc2NSl7dGFyZ2V0PSJfYmxhbmsifSAtIGZpbmUgcGFydGljbGUgZXhwb3N1cmUgKCoqUE1+Mi41fioqKSBmcm9tIHRyYWZmaWMtcmVsYXRlZCBhaXIgcG9sbHV0aW9uIHdhcyBhc3NvY2lhdGVkIHdpdGggaW5jcmVhc2VkIG1lYXN1cmVzIG9mIGluZmxhbW1hdG9yeSBtYXJrZXJzIGluIHlvdXRocyB3aXRoIFR5cGUgMSBkaWFiZXRlcwozKSBbTHVuZyBmdW5jdGlvbiBhbmQgZW1waHlzZW1hXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8zMTQwODEzNSl7dGFyZ2V0PSJfYmxhbmsifSAtIGhpZ2hlciBjb25jZW50cmF0aW9ucyBvZiBvem9uZSAoT34zfiksIG5pdHJvZ2VuIG94aWRlcyAoTk9+eH4pLCBibGFjayBjYXJib24sIGFuZCBmaW5lIHBhcnRpY2xlIGV4cG9zdXJlICoqUE1+Mi41fioqICwgYXQgc3R1ZHkgYmFzZWxpbmUgd2VyZSBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCBncmVhdGVyIGluY3JlYXNlcyBpbiBwZXJjZW50IGVtcGh5c2VtYSBwZXIgMTAgeWVhcnMgCjQpIFtMb3cgYmlydGh3ZWlnaHRdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcHVibWVkLzMxMzg2NjQzKXt0YXJnZXQ9Il9ibGFuayJ9IC0gZmluZSBwYXJ0aWNsZSBleHBvc3VyZSgqKlBNfjIuNX4qKikgd2FzIGFzc29jaWF0ZWQgd2l0aCBsb3dlciBiaXJ0aCB3ZWlnaHQgaW4gZnVsbC10ZXJtIGxpdmUgYmlydGhzCjUpIFtWaXJhbCBJbmZlY3Rpb25dKGh0dHBzOi8vd3d3LnRhbmRmb25saW5lLmNvbS9kb2kvZnVsbC8xMC4xMDgwLzA4OTU4MzcwNzAxNjY1NDM0KXt0YXJnZXQ9Il9ibGFuayJ9IC0gaGlnaGVyIHJhdGVzIG9mIGluZmVjdGlvbiBhbmQgaW5jcmVhc2VkIHNldmVyaXR5IG9mIGluZmVjdGlvbiBhcmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBleHBvc3VyZXMgdG8gcG9sbHV0aW9uIGxldmVscyBpbmNsdWRpbmcgZmluZSBwYXJ0aWNsZSBleHBvc3VyZSAoKipQTX4yLjV+KiopCgpTZWUgdGhpcyBbcmV2aWV3IGFydGljbGVdKGh0dHBzOi8vd3d3LmZyb250aWVyc2luLm9yZy9hcnRpY2xlcy8xMC4zMzg5L2ZwdWJoLjIwMjAuMDAwMTQvZnVsbCl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBzb3VyY2VzIG9mIGFpciBwb2xsdXRpb24gYW5kIHRoZSBpbmZsdWVuY2Ugb2YgYWlyIHBvbGx1dGlvbiBvbiBoZWFsdGguCgojIyMgU3BhcnNlIG1vbml0b3JpbmcgaXMgcHJvYmxlbWF0aWMgZm9yIFB1YmxpYyBIZWFsdGgKCkhpc3RvcmljYWxseSwgZXBpZGVtaW9sb2dpY2FsIHN0dWRpZXMgd291bGQgYXNzZXNzIHRoZSBpbmZsdWVuY2Ugb2YgYWlyIHBvbGx1dGlvbiBvbiBoZWFsdGggb3V0Y29tZXMgYnkgcmVseWluZyBvbiBhIG51bWJlciBvZiBtb25pdG9ycyBsb2NhdGVkIGFyb3VuZCB0aGUgY291bnRyeS4gCgpIb3dldmVyLCBhcyBjYW4gYmUgc2VlbiBpbiB0aGUgZm9sbG93aW5nIGZpZ3VyZSwgdGhlc2UgbW9uaXRvcnMgYXJlIHJlbGF0aXZlbHkgc3BhcnNlIGluIGNlcnRhaW4gcmVnaW9ucyBvZiB0aGUgY291bnRyeSBhbmQgYXJlIG5vdCBuZWNlc3NhcmlseSBsb2NhdGVkIG5lYXIgcG9sbHV0aW9uIHNvdXJjZXMuIFdlIHdpbGwgc2VlIGxhdGVyIHdoZW4gd2UgZXZhbHVhdGUgdGhlIGRhdGEsIHRoYXQgZXZlbiBpbiBjZXJ0YWluIHJlbGF0aXZlbHkgbGFyZ2UgY2l0aWVzIHRoZXJlIGlzIG9ubHkgIG9uZSBtb25pdG9yIQoKRnVydGhlcm1vcmUsIGRyYW1hdGljIGRpZmZlcmVuY2VzIGluIHBvbGx1dGlvbiByYXRlcyBjYW4gYmUgc2VlbiBldmVuIHdpdGhpbiB0aGUgc2FtZSBjaXR5LiBJbiBmYWN0LCB0aGUgdGVybSBtaWNyby1lbnZpcm9ubWVudHMgZGVzY3JpYmVzIGVudmlyb25tZW50IHdpdGhpbiBjaXRpZXMgb3IgY291bnRpZXMgd2hpY2ggbWF5IHZhcnkgZ3JlYXRseSBmcm9tIG9uZSBibG9jayB0byBhbm90aGVyLgoKYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoPSAiODAwIHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwgIm1hcF9vZl9tb25pdG9ycy5qcGciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vZWhqb3VybmFsLmJpb21lZGNlbnRyYWwuY29tL2FydGljbGVzLzEwLjExODYvMTQ3Ni0wNjlYLTEzLTYzKXt0YXJnZXQ9Il9ibGFuayJ9CgpUaGlzIGxhY2sgb2YgZ3JhbnVsYXJpdHkgaW4gYWlyIHBvbGx1dGlvbiBtb25pdG9yaW5nIGhhcyBoaW5kZXJlZCBvdXIgYWJpbGl0eSB0byBkaXNjZXJuIHRoZSBmdWxsIGltcGFjdCBvZiBhaXIgcG9sbHV0aW9uIG9uIGhlYWx0aCBhbmQgdG8gaWRlbnRpZnkgYXQtcmlzayBsb2NhdGlvbnMuIAoKCiMjIyBNYWNoaW5lIGxlYXJuaW5nIG9mZmVycyBhIHNvbHV0aW9uCgpBbiBbYXJ0aWNsZV0oaHR0cHM6Ly9laGpvdXJuYWwuYmlvbWVkY2VudHJhbC5jb20vYXJ0aWNsZXMvMTAuMTE4Ni8xNDc2LTA2OVgtMTMtNjMpe3RhcmdldD0iX2JsYW5rIn0gcHVibGlzaGVkIGluIHRoZSAqRW52aXJvbm1lbnRhbCBIZWFsdGgqIGpvdXJuYWwgZGVhbHQgd2l0aCB0aGlzIGlzc3VlIGJ5IHVzaW5nIGRhdGEsIGluY2x1ZGluZyBwb3B1bGF0aW9uIGRlbnNpdHksIHJvYWQgZGVuc2l0eSwgYW1vbmcgb3RoZXIgZmVhdHVyZXMsIHRvIG1vZGVsIG9yIHByZWRpY3QgYWlyIHBvbGx1dGlvbiBsZXZlbHMgYXQgYSBtb3JlIGxvY2FsaXplZCBzY2FsZSB1c2luZyBtYWNoaW5lIGxlYXJuaW5nIChNTCkgbWV0aG9kcy4gCgpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGg9ICI4MDAgcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCAidGhlcGFwZXIucG5nIikpCmBgYAoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL2Voam91cm5hbC5iaW9tZWRjZW50cmFsLmNvbS9hcnRpY2xlcy8xMC4xMTg2LzE0NzYtMDY5WC0xMy02Myl7dGFyZ2V0PSJfYmxhbmsifQoKIyMjIyB7LnJlZmVyZW5jZV9ibG9ja30KWWFub3NreSwgSi4gRC4gZXQgYWwuIFNwYXRpby10ZW1wb3JhbCBtb2RlbGluZyBvZiBwYXJ0aWN1bGF0ZSBhaXIgcG9sbHV0aW9uIGluIHRoZSBjb250ZXJtaW5vdXMgVW5pdGVkIFN0YXRlcyB1c2luZyBnZW9ncmFwaGljIGFuZCBtZXRlb3JvbG9naWNhbCBwcmVkaWN0b3JzLiAqRW52aXJvbiBIZWFsdGgqIDEzLCA2MyAoMjAxNCkuCgojIyMjCgpUaGUgYXV0aG9ycyBvZiB0aGlzIGFydGljbGUgc3RhdGUgdGhhdDoKCj4gIkV4cG9zdXJlIHRvIGF0bW9zcGhlcmljIHBhcnRpY3VsYXRlIG1hdHRlciAoUE0pIHJlbWFpbnMgYW4gaW1wb3J0YW50IHB1YmxpYyBoZWFsdGggY29uY2VybiwgYWx0aG91Z2ggaXQgcmVtYWlucyBkaWZmaWN1bHQgdG8gcXVhbnRpZnkgYWNjdXJhdGVseSBhY3Jvc3MgbGFyZ2UgZ2VvZ3JhcGhpYyBhcmVhcyB3aXRoIHN1ZmZpY2llbnRseSBoaWdoIHNwYXRpYWwgcmVzb2x1dGlvbi4gUmVjZW50IGVwaWRlbWlvbG9naWMgYW5hbHlzZXMgaGF2ZSBkZW1vbnN0cmF0ZWQgdGhlIGltcG9ydGFuY2Ugb2Ygc3BhdGlhbGx5LSBhbmQgdGVtcG9yYWxseS1yZXNvbHZlZCBleHBvc3VyZSBlc3RpbWF0ZXMsIHdoaWNoIHNob3cgbGFyZ2VyIFBNLW1lZGlhdGVkIGhlYWx0aCBlZmZlY3RzIGFzIGNvbXBhcmVkIHRvIG5lYXJlc3QgbW9uaXRvciBvciBjb3VudHktc3BlY2lmaWMgYW1iaWVudCBjb25jZW50cmF0aW9ucy4iIAoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL2Voam91cm5hbC5iaW9tZWRjZW50cmFsLmNvbS9hcnRpY2xlcy8xMC4xMTg2LzE0NzYtMDY5WC0xMy02Myl7dGFyZ2V0PSJfYmxhbmsifQoKVGhlIGFydGljbGUgYWJvdmUgZGVtb25zdHJhdGVzIHRoYXQgbWFjaGluZSBsZWFybmluZyBtZXRob2RzIGNhbiBiZSB1c2VkIHRvIHByZWRpY3QgYWlyIHBvbGx1dGlvbiBsZXZlbHMgd2hlbiB0cmFkaXRpb25hbCBtb25pdG9yaW5nIHN5c3RlbXMgYXJlIG5vdCBhdmFpbGFibGUgaW4gYSBwYXJ0aWN1bGFyIGFyZWEgb3Igd2hlbiB0aGVyZSBpcyBub3QgZW5vdWdoIHNwYXRpYWwgZ3JhbnVsYXJpdHkgd2l0aCBjdXJyZW50IG1vbml0b3Jpbmcgc3lzdGVtcy4gCldlIHdpbGwgdXNlIHNpbWlsYXIgbWV0aG9kcyB0byBwcmVkaWN0IGFubnVhbCBhaXIgcG9sbHV0aW9uIGxldmVscyBzcGF0aWFsbHkgd2l0aGluIHRoZSBVUy4KCgojICoqTWFpbiBRdWVzdGlvbioqCioqKgoKIyMjIyB7Lm1haW5fcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBPdXIgbWFpbiBxdWVzdGlvbjogPC91PjwvYj4KCjEpIENhbiB3ZSBwcmVkaWN0IGFubnVhbCBhdmVyYWdlIGFpciBwb2xsdXRpb24gY29uY2VudHJhdGlvbnMgYXQgdGhlIGdyYW51bGFyaXR5IG9mIHppcCBjb2RlIHJlZ2lvbmFsIGxldmVscyB1c2luZyBwcmVkaWN0b3JzIHN1Y2ggYXMgZGF0YSBhYm91dCBwb3B1bGF0aW9uIGRlbnNpdHksIHVyYmFuaXphdGlvbiwgcm9hZCBkZW5zaXR5LCBhcyB3ZWxsIGFzLCBzYXRlbGxpdGUgcG9sbHV0aW9uIGRhdGEgYW5kIGNoZW1pY2FsIG1vZGVsaW5nIGRhdGE/CgojIyMjCgojICoqTGVhcm5pbmcgT2JqZWN0aXZlcyoqCioqKgoKSW4gdGhpcyBjYXNlIHN0dWR5LCB3ZSB3aWxsIHdhbGsgeW91IHRocm91Z2ggaW1wb3J0aW5nIGRhdGEgZnJvbSBDU1YgZmlsZXMgYW5kIHBlcmZvcm1pbmcgbWFjaGluZSBsZWFybmluZyBtZXRob2RzIHRvIHByZWRpY3Qgb3VyIG91dGNvbWUgdmFyaWFibGUgb2YgaW50ZXJlc3QgKGluIHRoaXMgY2FzZSBhbm51YWwgZmluZSBwYXJ0aWNsZSBhaXIgcG9sbHV0aW9uIGVzdGltYXRlcykuIAoKV2Ugd2lsbCBlc3BlY2lhbGx5IGZvY3VzIG9uIHVzaW5nIHBhY2thZ2VzIGFuZCBmdW5jdGlvbnMgZnJvbSB0aGUgW2B0aWR5dmVyc2VgXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSwgYW5kIG1vcmUgc3BlY2lmaWNhbGx5IHRoZSBbYHRpZHltb2RlbHNgXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvdGlkeW1vZGVscy90aWR5bW9kZWxzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSBwYWNrYWdlL2Vjb3N5c3RlbSBwcmltYXJpbHkgZGV2ZWxvcGVkIGFuZCBtYWludGFpbmVkIGJ5IFtNYXggS3Vobl0oaHR0cHM6Ly9yZXNvdXJjZXMucnN0dWRpby5jb20vYXV0aG9ycy9tYXgta3Vobil7dGFyZ2V0PSJfYmxhbmsifSBhbmQgW0RhdmlzIFZhdWdoYW5dKGh0dHBzOi8vcmVzb3VyY2VzLnJzdHVkaW8uY29tL2F1dGhvcnMvZGF2aXMtdmF1Z2hhbil7dGFyZ2V0PSJfYmxhbmsifS4gClRoaXMgcGFja2FnZSBsb2FkcyBtb3JlIG1vZGVsaW5nIHJlbGF0ZWQgcGFja2FnZXMgbGlrZSBgcnNhbXBsZWAsIGByZWNpcGVzYCwgYHBhcnNuaXBgLCBgeWFyZHN0aWNrYCwgYHdvcmtmbG93c2AsIGFuZCBgdHVuZWAgcGFja2FnZXMuIAoKVGhlIHRpZHl2ZXJzZSBpcyBhIGxpYnJhcnkgb2YgcGFja2FnZXMgY3JlYXRlZCBieSBSU3R1ZGlvLiAKV2hpbGUgc29tZSBzdHVkZW50cyBtYXkgYmUgZmFtaWxpYXIgd2l0aCBwcmV2aW91cyBSIHByb2dyYW1taW5nIHBhY2thZ2VzLCB0aGVzZSBwYWNrYWdlcyBtYWtlIGRhdGEgc2NpZW5jZSBpbiBSIGVzcGVjaWFsbHkgbGVnaWJsZSBhbmQgaW50dWl0aXZlLgoKCmBgYHtyLCBvdXQud2lkdGggPSAiMjAlIiwgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ24gPSJjZW50ZXIifQppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL3RpZHl2ZXJzZS50aWR5dmVyc2Uub3JnL2xvZ28ucG5nIikKYGBgCgpUaGUgc2tpbGxzLCBtZXRob2RzLCBhbmQgY29uY2VwdHMgdGhhdCBzdHVkZW50cyB3aWxsIGJlIGZhbWlsaWFyIHdpdGggYnkgdGhlIGVuZCBvZiB0aGlzIGNhc2Ugc3R1ZHkgYXJlOgoKCjx1PioqRGF0YSBTY2llbmNlIExlYXJuaW5nIE9iamVjdGl2ZXM6Kio8L3U+IAogIAoxLiBGYW1pbGlhcml0eSB3aXRoIHRoZSB0aWR5bW9kZWxzIGVjb3N5c3RlbQoyLiBBYmlsaXR5IHRvIGV2YWx1YXRlIGNvcnJlbGF0aW9uIGFtb25nIHByZWRpY3RvciB2YXJpYWJsZXMgKGBjb3JycGxvdGAgYW5kIGBHR2FsbHlgKQozLiBBYmlsaXR5IHRvIGltcGxlbWVudCB0aWR5bW9kZWxzIHBhY2thZ2VzIHN1Y2ggYXMgYHJzYW1wbGVgIHRvIHNwbGl0IHRoZSBkYXRhIGludG8gdHJhaW5pbmcgYW5kIHRlc3Rpbmcgc2V0cyBhcyB3ZWxsIGFzIGNyb3NzIHZhbGlkYXRpb24gc2V0cy4KNC4gQWJpbGl0eSB0byB1c2UgdGhlIGByZWNpcGVzYCwgYHBhcnNuaXBgLCBhbmQgYHdvcmtmbG93c2AgdG8gdHJhaW4gYW5kIHRlc3QgYSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCBhbmQgcmFuZG9tIGZvcmVzdCBtb2RlbAo1LiBEZW1vbnN0cmF0ZSBob3cgdG8gdmlzdWFsaXplIGdlby1zcGF0aWFsIGRhdGEgdXNpbmcgYGdncGxvdDJgCgo8dT4qKlN0YXRpc3RpY2FsIExlYXJuaW5nIE9iamVjdGl2ZXM6Kio8L3U+ICAKICAKMS4gQmFzaWMgdW5kZXJzdGFuZGluZyB0aGUgdXRpbGl0eSBvZiBtYWNoaW5lIGxlYXJuaW5nIGZvciBwcmVkaWN0aW9uIGFuZCBjbGFzc2lmaWNhdGlvbgoyLiBVbmRlcnN0YW5kaW5nIG9mIHRoZSBuZWVkIGZvciB0cmFpbmluZyBhbmQgdGVzdCBzZXRzCjMuIFVuZGVyc3RhbmRpbmcgb2YgdGhlIHV0aWxpdHkgb2YgY3Jvc3MgdmFsaWRhdGlvbgo0LiBVbmRlcnN0YW5kaW5nIG9mIHJhbmRvbSBmb3Jlc3QKNS4gSG93IHRvIGludGVycHJldCByb290IG1lYW4gc3F1YXJlZCBlcnJvciAocm1zZSkgdG8gYXNzZXNzIHBlcmZvcm1hbmNlIGZvciBwcmVkaWN0aW9uCgoKCmBgYHtyLCBvdXQud2lkdGggPSAiMTAwcHgiLCBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbiA9ImNlbnRlciJ9CmluY2x1ZGVfZ3JhcGhpY3MoImh0dHBzOi8vcGJzLnR3aW1nLmNvbS9tZWRpYS9Ea0JGcFNzVzRBSXl5SU4ucG5nIikKYGBgCgoKV2Ugd2lsbCBiZWdpbiBieSBsb2FkaW5nIHRoZSBwYWNrYWdlcyB0aGF0IHdlIHdpbGwgbmVlZDoKCmBgYHtyfQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoc2tpbXIpCmxpYnJhcnkoc3VtbWFyeXRvb2xzKQpsaWJyYXJ5KG1hZ3JpdHRyKQpsaWJyYXJ5KGNvcnJwbG90KQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeShHR2FsbHkpCmxpYnJhcnkodGlkeW1vZGVscykKbGlicmFyeSh3b3JrZmxvd3MpCmxpYnJhcnkodmlwKQpsaWJyYXJ5KHR1bmUpCmxpYnJhcnkocmFuZG9tRm9yZXN0KQpsaWJyYXJ5KGRvUGFyYWxsZWwpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGx3Z2VvbSkKbGlicmFyeShzZikKbGlicmFyeShtYXBzKQpsaWJyYXJ5KHJuYXR1cmFsZWFydGgpCmxpYnJhcnkocmdlb3MpCmxpYnJhcnkocGF0Y2h3b3JrKQpgYGAKCgogPHU+KipQYWNrYWdlcyB1c2VkIGluIHRoaXMgY2FzZSBzdHVkeToqKiA8L3U+CgpQYWNrYWdlICAgfCBVc2UgaW4gdGhpcyBjYXNlIHN0dWR5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotLS0tLS0tLS0tIHwtLS0tLS0tLS0tLS0tCltoZXJlXShodHRwczovL2dpdGh1Yi5jb20vamVubnliYy9oZXJlX2hlcmUpe3RhcmdldD0iX2JsYW5rIn0gICAgICAgfCB0byBlYXNpbHkgbG9hZCBhbmQgc2F2ZSBkYXRhCltyZWFkcl0oaHR0cHM6Ly9yZWFkci50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gaW1wb3J0IENTViBmaWxlcwpbZHBseXJdKGh0dHBzOi8vZHBseXIudGlkeXZlcnNlLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gICAgICB8IHRvIHZpZXcvYXJyYW5nZS9maWx0ZXIvc2VsZWN0L2NvbXBhcmUgc3BlY2lmaWMgc3Vic2V0cyBvZiBkYXRhIApbc2tpbXJdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9za2ltci9pbmRleC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAgICAgfCB0byBnZXQgYW4gb3ZlcnZpZXcgb2YgZGF0YQpbc3VtbWFyeXRvb2xzXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvc2tpbXIvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gZ2V0IGFuIG92ZXJ2aWV3IG9mIGRhdGEgaW4gYSBkaWZmZXJlbnQgc3R5bGUKW21hZ3JpdHRyXShodHRwczovL21hZ3JpdHRyLnRpZHl2ZXJzZS5vcmcvYXJ0aWNsZXMvbWFncml0dHIuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgdG8gdXNlIHRoZSBgJTw+JWAgcGlwcGluZyBvcGVyYXRvciAKW2NvcnJwbG90XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvY29ycnBsb3QvdmlnbmV0dGVzL2NvcnJwbG90LWludHJvLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBtYWtlIGxhcmdlIGNvcnJlbGF0aW9uIHBsb3RzCltHR2FsbHldKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9HR2FsbHkvR0dhbGx5LnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIG1ha2Ugc21hbGxlciBjb3JyZWxhdGlvbiBwbG90cyAgClt0aWR5bW9kZWxzXShodHRwczovL3d3dy50aWR5bW9kZWxzLm9yZyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGxvYWQgaW4gYSBzZXQgb2YgcGFja2FnZXMgKGJyb29tLCBkaWFscywgaW5mZXIsIHBhcnNuaXAsIHB1cnJyLCByZWNpcGVzLCByc2FtcGxlLCB0aWJibGUsIHlhcmRzdGljaykKW3JzYW1wbGVdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcnNhbXBsZS9hcnRpY2xlcy9CYXNpY3MuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgdG8gc3BsaXQgdGhlIGRhdGEgaW50byB0ZXN0aW5nIGFuZCB0cmFpbmluZyBzZXRzOyB0byBzcGxpdCB0aGUgdHJhaW5pbmcgc2V0IGZvciBjcm9zcy12YWxpZGF0aW9uICAKW3JlY2lwZXNdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcmVjaXBlcy8pe3RhcmdldD0iX2JsYW5rIn0gICB8IHRvIHByZS1wcm9jZXNzIGRhdGEgZm9yIG1vZGVsaW5nIGluIGEgdGlkeSBhbmQgcmVwcm9kdWNpYmxlIHdheSBhbmQgdG8gZXh0cmFjdCBwcmUtcHJvY2Vzc2VkIGRhdGEgKG1ham9yIGZ1bmN0aW9ucyBhcmUgYHJlY2lwZSgpYCwgYHByZXAoKWAgYW5kIHZhcmlvdXMgdHJhbnNmb3JtYXRpb24gYHN0ZXBfKigpYCBmdW5jdGlvbnMsIGFzIHdlbGwgYXMgYGJha2VgIHdoaWNoIGV4dHJhY3RzIHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YSAodXNlZCB0byByZXF1aXJlIGBqdWljZSgpYCkgYW5kIGFwcGxpZXMgcmVjaXBlIHByZXByb2Nlc3Npbmcgc3RlcHMgdG8gdGVzdGluZyBkYXRhKS4gU2VlIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmVjaXBlcy9yZWNpcGVzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSAgZm9yIG1vcmUgaW5mby4KW3BhcnNuaXBdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcGFyc25pcC8pe3RhcmdldD0iX2JsYW5rIn0gICB8IGFuIGludGVyZmFjZSB0byBjcmVhdGUgbW9kZWxzIChtYWpvciBmdW5jdGlvbnMgYXJlIGBmaXQoKWAsIGBzZXRfZW5naW5lKClgKQpbeWFyZHN0aWNrXShodHRwczovL3RpZHltb2RlbHMuZ2l0aHViLmlvL3lhcmRzdGljay8pe3RhcmdldD0iX2JsYW5rIn0gICB8IHRvIGV2YWx1YXRlIHRoZSBwZXJmb3JtYW5jZSBvZiBtb2RlbHMKW2Jyb29tXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnL2Jsb2cvMjAxOC8wNy9icm9vbS0wLTUtMC8pe3RhcmdldD0iX2JsYW5rIn0gfCB0byBnZXQgdGlkeSBvdXRwdXQgZm9yIG91ciBtb2RlbCBmaXQgYW5kIHBlcmZvcm1hbmNlCltnZ3Bsb3QyXShodHRwczovL2dncGxvdDIudGlkeXZlcnNlLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gICAgfCB0byBtYWtlIHZpc3VhbGl6YXRpb25zIHdpdGggbXVsdGlwbGUgbGF5ZXJzCltkaWFsc10oaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZy9ibG9nLzIwMTkvMTAvZGlhbHMtMC0wLTMvKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gc3BlY2lmeSBoeXBlci1wYXJhbWV0ZXIgdHVuaW5nClt0dW5lXShodHRwczovL3R1bmUudGlkeW1vZGVscy5vcmcvKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gcGVyZm9ybSBjcm9zcyB2YWxpZGF0aW9uLCB0dW5lIGh5cGVyLXBhcmFtZXRlcnMsIGFuZCBnZXQgcGVyZm9ybWFuY2UgbWV0cmljcwpbd29ya2Zsb3dzXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvd29ya2Zsb3dzL3ZlcnNpb25zLzAuMS4xKXt0YXJnZXQ9Il9ibGFuayJ9fCB0byBjcmVhdGUgbW9kZWxpbmcgd29ya2Zsb3cgdG8gc3RyZWFtbGluZSB0aGUgbW9kZWxpbmcgcHJvY2VzcwpbdmlwXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvdmlwL3ZpcC5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBjcmVhdGUgdmFyaWFibGUgaW1wb3J0YW5jZSBwbG90cwpbcmFuZG9tRm9yZXN0XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmFuZG9tRm9yZXN0L3JhbmRvbUZvcmVzdC5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBwZXJmb3JtIHRoZSByYW5kb20gZm9yZXN0IGFuYWx5c2lzCltkb1BhcmFsbGVsXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZG9QYXJhbGxlbC9kb1BhcmFsbGVsLnBkZikgfCB0byBmaXQgY3Jvc3MgdmFsaWRhdGlvbiBzYW1wbGVzIGluIHBhcmFsbGVsIApbc3RyaW5ncl0oaHR0cHM6Ly9zdHJpbmdyLnRpZHl2ZXJzZS5vcmcvYXJ0aWNsZXMvc3RyaW5nci5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAgIHwgdG8gbWFuaXB1bGF0ZSB0aGUgdGV4dCB0aGUgbWFwIGRhdGEKW3RpZHlyXShodHRwczovL3RpZHlyLnRpZHl2ZXJzZS5vcmcvKXt0YXJnZXQ9Il9ibGFuayJ9ICAgICAgfCB0byBzZXBhcmF0ZSBkYXRhIHdpdGhpbiBhIGNvbHVtbiBpbnRvIG11bHRpcGxlIGNvbHVtbnMKW3JuYXR1cmFsZWFydGhdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9ybmF0dXJhbGVhcnRoL1JFQURNRS5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gZ2V0IHRoZSBnZW9tZXRyeSBkYXRhIGZvciB0aGUgZWFydGggdG8gcGxvdCB0aGUgVVMKW21hcHNdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9tYXBzL21hcHMucGRmKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gZ2V0IG1hcCBkYXRhYmFzZSBkYXRhIGFib3V0IGNvdW50aWVzIHRvIGRyYXcgdGhlbSBvbiBvdXIgVVMgbWFwCltzZl0oaHR0cHM6Ly9yLXNwYXRpYWwuZ2l0aHViLmlvL3NmLyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGNvbnZlcnQgdGhlIG1hcCBkYXRhIGludG8gYSBkYXRhIGZyYW1lCltsd2dlb21dKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9sd2dlb20vbHdnZW9tLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHVzZSB0aGUgYHNmYCBmdW5jdGlvbiB0byBjb252ZXJ0IG1hcCBnZW9ncmFwaGljYWwgZGF0YQpbcmdlb3NdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yZ2Vvcy9yZ2Vvcy5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byB1c2UgZ2VvbWV0cnkgZGF0YQpbcGF0Y2h3b3JrXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcGF0Y2h3b3JrL3BhdGNod29yay5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBhbGxvdyBwbG90cyB0byBiZSBjb21iaW5lZApfX18KCgpUaGUgZmlyc3QgdGltZSB3ZSB1c2UgYSBmdW5jdGlvbiwgd2Ugd2lsbCB1c2UgdGhlIGA6OmAgdG8gaW5kaWNhdGUgd2hpY2ggcGFja2FnZSB3ZSBhcmUgdXNpbmcuIApVbmxlc3Mgd2UgaGF2ZSBvdmVybGFwcGluZyBmdW5jdGlvbiBuYW1lcywgdGhpcyBpcyBub3QgbmVjZXNzYXJ5LCBidXQgd2Ugd2lsbCBpbmNsdWRlIGl0IGhlcmUgdG8gYmUgaW5mb3JtYXRpdmUgYWJvdXQgd2hlcmUgdGhlIGZ1bmN0aW9ucyB3ZSB3aWxsIHVzZSBjb21lIGZyb20uCgoKIyAqKkNvbnRleHQqKgoqKioKClRoZSBbU3RhdGUgb2YgR2xvYmFsIEFpcl0oaHR0cHM6Ly93d3cuc3RhdGVvZmdsb2JhbGFpci5vcmcvKXt0YXJnZXQ9Il9ibGFuayJ9IGlzIGEgcmVwb3J0IHJlbGVhc2VkIGV2ZXJ5IHllYXIgdG8gY29tbXVuaWNhdGUgdGhlIGltcGFjdCBvZiBhaXIgcG9sbHV0aW9uIG9uIHB1YmxpYyBoZWFsdGguIAoKVGhlIFtTdGF0ZSBvZiBHbG9iYWwgQWlyIDIwMTkgcmVwb3J0XShodHRwczovL3d3dy5zdGF0ZW9mZ2xvYmFsYWlyLm9yZy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3NvZ2FfMjAxOV9yZXBvcnQucGRmKXt0YXJnZXQ9Il9ibGFuayJ9CndoaWNoIHVzZXMgZGF0YSBmcm9tIDIwMTcgc3RhdGVkIHRoYXQ6Cgo+IEFpciBwb2xsdXRpb24gaXMgdGhlICoqZmlmdGgqKiBsZWFkaW5nIHJpc2sgZmFjdG9yIGZvciBtb3J0YWxpdHkgd29ybGR3aWRlLiBJdCBpcyByZXNwb25zaWJsZSBmb3IgbW9yZQpkZWF0aHMgdGhhbiBtYW55IGJldHRlci1rbm93biByaXNrIGZhY3RvcnMgc3VjaCBhcyBtYWxudXRyaXRpb24sIGFsY29ob2wgdXNlLCBhbmQgcGh5c2ljYWwgaW5hY3Rpdml0eS4KRWFjaCB5ZWFyLCAqKm1vcmUqKiBwZW9wbGUgZGllIGZyb20gYWlyIHBvbGx1dGlvbuKAk3JlbGF0ZWQgZGlzZWFzZSB0aGFuIGZyb20gcm9hZCAqKnRyYWZmaWMgaW5qdXJpZXMqKiBvciAqKm1hbGFyaWEqKi4KCjxwIGFsaWduPSJjZW50ZXIiPgo8aW1nIHdpZHRoPSI2MDAiIHNyYz0iaHR0cHM6Ly93d3cuaGVhbHRoZWZmZWN0cy5vcmcvc2l0ZXMvZGVmYXVsdC9maWxlcy9Tb0dBLUZpZ3VyZXMtMDEuanBnIj4KPC9wPgoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL3d3dy5zdGF0ZW9mZ2xvYmFsYWlyLm9yZy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3NvZ2FfMjAxOV9yZXBvcnQucGRmKXt0YXJnZXQ9Il9ibGFuayJ9CgpUaGUgcmVwb3J0IGFsc28gc3RhdGVkIHRoYXQ6Cgo+IEluIDIwMTcsIGFpciBwb2xsdXRpb24gaXMgZXN0aW1hdGVkIHRvIGhhdmUgY29udHJpYnV0ZWQgdG8gY2xvc2UgdG8gNSBtaWxsaW9uCmRlYXRocyBnbG9iYWxseSDigJQgbmVhcmx5ICoqMSBpbiBldmVyeSAxMCBkZWF0aHMqKi4KCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0iODAwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCIyMDE3ZGVhdGhzLnBuZyIpKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cuc3RhdGVvZmdsb2JhbGFpci5vcmcvc2l0ZXMvZGVmYXVsdC9maWxlcy9zb2dhXzIwMTlfZmFjdF9zaGVldC5wZGYpe3RhcmdldD0iX2JsYW5rIn0KClRoZSBbU3RhdGUgb2YgR2xvYmFsIEFpciAyMDE4IHJlcG9ydF0oaHR0cHM6Ly93d3cuc3RhdGVvZmdsb2JhbGFpci5vcmcvc2l0ZXMvZGVmYXVsdC9maWxlcy9zb2dhLTIwMTgtcmVwb3J0LnBkZil7dGFyZ2V0PSJfYmxhbmsifSB1c2luZyBkYXRhIGZyb20gMjAxNiB3aGljaCBzZXBhcmF0ZWQgZGlmZmVyZW50IHR5cGVzIG9mIGFpciBwb2xsdXRpb24sIGZvdW5kIHRoYXQgKipwYXJ0aWN1bGF0ZSBwb2xsdXRpb24gd2FzIHBhcnRpY3VsYXJseSBhc3NvY2lhdGVkIHdpdGggbW9ydGFsaXR5KiouCgpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwiMjAxN21vcnRhbGl0eS5wbmciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3LnN0YXRlb2ZnbG9iYWxhaXIub3JnL3NpdGVzL2RlZmF1bHQvZmlsZXMvc29nYS0yMDE4LXJlcG9ydC5wZGYpe3RhcmdldD0iX2JsYW5rIn0KClRoZSAyMDE5IHJlcG9ydCBzaG93cyB0aGF0IHRoZSBoaWdoZXN0IGxldmVscyBvZiBmaW5lIHBhcnRpY3VsYXRlIHBvbGx1dGlvbiBvY2N1cnMgaW4gQWZyaWNhIGFuZCBBc2lhIGFuZCB0aGF0OgoKPiBNb3JlIHRoYW4gKio5MCUqKiBvZiBwZW9wbGUgd29ybGR3aWRlIGxpdmUgaW4gYXJlYXMgKipleGNlZWRpbmcqKiB0aGUgV29ybGQgSGVhbHRoIE9yZ2FuaXphdGlvbiAoV0hPKSAqKkd1aWRlbGluZSoqIGZvciBoZWFsdGh5IGFpci4gTW9yZSB0aGFuIGhhbGYgbGl2ZSBpbiBhcmVhcyB0aGF0IGRvIG5vdCBldmVuIG1lZXQgV0hPJ3MgbGVhc3Qtc3RyaW5nZW50IGFpciBxdWFsaXR5IHRhcmdldC4KCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0iODAwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCJQTXdvcmxkLnBuZyIpKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cuc3RhdGVvZmdsb2JhbGFpci5vcmcvc2l0ZXMvZGVmYXVsdC9maWxlcy9zb2dhXzIwMTlfZmFjdF9zaGVldC5wZGYpe3RhcmdldD0iX2JsYW5rIn0KCkxvb2tpbmcgYXQgdGhlIFVTIHNwZWNpZmljYWxseSwgYWlyIHBvbGx1dGlvbiBsZXZlbHMgYXJlIGdlbmVyYWxseSBpbXByb3ZpbmcsIHdpdGggZGVjbGluaW5nIG5hdGlvbmFsIGFpciBwb2xsdXRhbnQgY29uY2VudHJhdGlvbiBhdmVyYWdlcyBhcyBzaG93biBmcm9tIHRoZSAyMDE5IFsqT3VyIE5hdGlvbidzIEFpcipdKGh0dHBzOi8vZ2lzcHViLmVwYS5nb3YvYWlyL3RyZW5kc3JlcG9ydC8yMDE5LyNob21lKXt0YXJnZXQ9Il9ibGFuayJ9IHJlcG9ydCBmcm9tIHRoZSBVUyBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpOiAKCmBgYHtyLCBlY2hvID0gRkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJVUy5wbmciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vZ2lzcHViLmVwYS5nb3YvYWlyL3RyZW5kc3JlcG9ydC8yMDE5L2RvY3VtZW50YXRpb24vQWlyVHJlbmRzX0ZseWVyLnBkZil7dGFyZ2V0PSJfYmxhbmsifQoKSG93ZXZlciwgYWlyIHBvbGx1dGlvbiAqKmNvbnRpbnVlcyB0byBjb250cmlidXRlIHRvIGhlYWx0aCByaXNrIGZvciBBbWVyaWNhbnMqKiwgaW4gcGFydGljdWxhciBpbiAqKnJlZ2lvbnMgd2l0aCBoaWdoZXIgdGhhbiBuYXRpb25hbCBhdmVyYWdlIHJhdGVzKiogb2YgcG9sbHV0aW9uIHRoYXQgYWN0dWFsbHkgYXQgdGltZSBleGNlZWQgdGhlIFdITydzIHJlY29tbWVuZGVkIGxldmVsLiAKVGh1cywgaXQgaXMgaW1wb3J0YW50IHRvIG9idGFpbiBoaWdoIHNwYXRpYWwgZ3JhbnVsYXJpdHkgaW4gZXN0aW1hdGVzIG9mIGFpciBwb2xsdXRpb24gaW4gb3JkZXIgdG8gaWRlbnRpZnkgbG9jYXRpb25zIHdoZXJlIHBvcHVsYXRpb25zIGFyZSBleHBlcmllbmNpbmcgaGFybWZ1bCBsZXZlbHMgb2YgZXhwb3N1cmUuCgpZb3UgY2FuIHNlZSB0aGF0IGN1cnJlbnQgYWlyIHF1YWxpdHkgY29uZGl0aW9ucyBhdCB0aGlzIFt3ZWJzaXRlXShodHRwczovL2FxaWNuLm9yZy9jaXR5L3VzYS8pe3RhcmdldD0iX2JsYW5rIn0gYW5kIHlvdSB3aWxsIG5vdGljZSB2YXJpYXRpb24gYWNyb3NzIGRpZmZlcmVudCBjaXRpZXMuCgpGb3IgZXhhbXBsZSwgaGVyZSBhcmUgdGhlIGNvbmRpdGlvbnMgaW4gVG9wZWthIEthbnNhcyBhdCB0aGUgdGltZSB0aGlzIGNhc2Ugc3R1ZHkgd2FzIGNyZWF0ZWQ6CgpgYGB7ciwgZWNobyA9IEZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCAiS2Fuc2FzLnBuZyIpKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly9hcWljbi5vcmcvY2l0eS91c2EvKXt0YXJnZXQ9Il9ibGFuayJ9CgpJdCByZXBvcnRzIHBhcnRpY3VsYXRlIHZhbHVlcyB1c2luZyB3aGF0IGlzIGNhbGxlZCB0aGUgW0FpciBRdWFsaXR5IEluZGV4XShodHRwczovL3d3dy5haXJub3cuZ292L2luZGV4LmNmbT9hY3Rpb249YXFpYmFzaWNzLmFxaSl7dGFyZ2V0PSJfYmxhbmsifSAoQVFJKS4KVGhpcyBbY2FsY3VsYXRvcl0oaHR0cHM6Ly9haXJub3cuZ292L2luZGV4LmNmbT9hY3Rpb249YWlybm93LmNhbGN1bGF0b3Ipe3RhcmdldD0iX2JsYW5rIn0gaW5kaWNhdGVzIHRoYXQgMTE0IEFRSSBpcyBlcXVpdmFsZW50IHRvIDQwLjcgdWcvbV4zXiBhbmQgaXMgY29uc2lkZXJlZCB1bmhlYWx0aHkgZm9yIHNlbnNpdGl2ZSBpbmRpdmlkdWFscy4KVGh1cywgc29tZSBhcmVhcyBleGNlZWQgdGhlIFdITyBhbm51YWwgZXhwb3N1cmUgZ3VpZGVsaW5lICgxMCB1Zy9tXjNeKSBhbmQgdGhpcyBtYXkgYWR2ZXJzZWx5IGFmZmVjdCB0aGUgaGVhbHRoIG9mIHBlb3BsZSBsaXZpbmcgaW4gdGhlc2UgbG9jYXRpb25zLgoKQWR2ZXJzZSBoZWFsdGggZWZmZWN0cyBoYXZlIGJlZW4gYXNzb2NpYXRlZCB3aXRoIHBvcHVsYXRpb25zIGV4cGVyaWVuY2luZyBoaWdoZXIgcG9sbHV0aW9uIGV4cG9zdXJlIGRlc3BpdGUgdGhlIGxldmVscyBiZWluZyBiZWxvdyBzdWdnZXN0ZWQgZ3VpZGVsaW5lcy4gCkFsc28sIGl0IGFwcGVhcnMgdGhhdCB0aGUgY29tcG9zaXRpb24gb2YgdGhlIHBhcnRpY3VsYXRlIG1hdHRlciBhbmQgdGhlIGluZmx1ZW5jZSBvZiBvdGhlciBkZW1vZ3JhcGhpYyBmYWN0b3JzIG1heSBtYWtlIHNwZWNpZmljIHBvcHVsYXRpb25zIG1vcmUgYXQgcmlzayBmb3IgYWR2ZXJzZSBoZWFsdGggZWZmZWN0cyBkdWUgdG8gYWlyIHBvbGx1dGlvbi4gCkZvciBleGFtcGxlLCBzZWUgdGhpcyBbYXJ0aWNsZV0oaHR0cHM6Ly93d3cubmVqbS5vcmcvZG9pL2Z1bGwvMTAuMTA1Ni9ORUpNb2ExNzAyNzQ3KXt0YXJnZXQ9Il9ibGFuayJ9IGZvciBtb3JlIGRldGFpbHMuCgpUaGUgbW9uaXRvciBkYXRhIHRoYXQgd2Ugd2lsbCB1c2UgaW4gdGhpcyBjYXNlIHN0dWR5IGNvbWUgZnJvbSBhIHN5c3RlbSBvZiBtb25pdG9ycyBpbiB3aGljaCByb3VnaGx5IDkwJSBhcmUgbG9jYXRlZCB3aXRoaW4gY2l0aWVzLiAKSGVuY2UsIHRoZXJlIGlzIGFuICoqZXF1aXR5IGlzc3VlKiogaW4gdGVybXMgb2YgY2FwdHVyaW5nIHRoZSBhaXIgcG9sbHV0aW9uIGxldmVscyBvZiBtb3JlIHJ1cmFsIGFyZWFzLiAKVG8gZ2V0IGEgYmV0dGVyIHNlbnNlIG9mIHRoZSBwb2xsdXRpb24gZXhwb3N1cmVzIGZvciB0aGUgaW5kaXZpZHVhbHMgbGl2aW5nIGluIHRoZXNlIGFyZWFzLCBtZXRob2RzIGxpa2UgbWFjaGluZSBsZWFybmluZyBjYW4gYmUgdXNlZnVsIHRvIGVzdGltYXRlIGFpciBwb2xsdXRpb24gbGV2ZWxzIGluICoqYXJlYXMgd2l0aCBsaXR0bGUgdG8gbm8gbW9uaXRvcmluZyoqLiAKU3BlY2lmaWNhbGx5LCB0aGVzZSBtZXRob2RzIGNhbiBiZSB1c2VkIHRvIGVzdGltYXRlIGFpciBwb2xsdXRpb24gaW4gdGhlc2UgbG93IG1vbml0b3JpbmcgYXJlYXMgc28gdGhhdCB3ZSBjYW4gbWFrZSBhIG1hcCBsaWtlIHRoaXMgd2hlcmUgd2UgaGF2ZSBhbm51YWwgZXN0aW1hdGVzIGZvciBhbGwgb2YgdGhlIGNvbnRpZ3VvdXMgVVM6Cgo8cCBhbGlnbj0iY2VudGVyIj4KICA8aW1nIHdpZHRoPSI2MDAiIHNyYz0iaHR0cHM6Ly9hcmMtYW5nbGVyZmlzaC13YXNocG9zdC1wcm9kLXdhc2hwb3N0LnMzLmFtYXpvbmF3cy5jb20vcHVibGljL1NBV09FR0JYTVZHUTdBUzVQWjZVVU9YNkZZLnBuZyI+CjwvcD4KCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS91cmw/c2E9aSZ1cmw9aHR0cHMlM0ElMkYlMkZ3d3cud2FzaGluZ3RvbnBvc3QuY29tJTJGYnVzaW5lc3MlMkYyMDE5JTJGMTAlMkYyMyUyRmFpci1wb2xsdXRpb24taXMtZ2V0dGluZy13b3JzZS1kYXRhLXNob3ctbW9yZS1wZW9wbGUtYXJlLWR5aW5nJTJGJnBzaWc9QU92VmF3M3YtWkRUQlBuTFAyTVl0S2YzVW5kaiZ1c3Q9MTU4NTc4NDQ3OTA2ODAwMCZzb3VyY2U9aW1hZ2VzJmNkPXZmZSZ2ZWQ9MENBSVFqUnhxRndvVENQQ3luOWZ4eGVnQ0ZRQUFBQUFkQUFBQUFCQWQpe3RhcmdldD0iX2JsYW5rIn0KClRoaXMgaXMgd2hhdCB3ZSBhaW0gdG8gYWNoaWV2ZSBpbiB0aGlzIGNhc2Ugc3R1ZHkuCgojICoqTGltaXRhdGlvbnMqKgoqKioKClRoZXJlIGFyZSBzb21lIGltcG9ydGFudCBjb25zaWRlcmF0aW9ucyByZWdhcmRpbmcgdGhlIGRhdGEgYW5hbHlzaXMgaW4gdGhpcyBjYXNlIHN0dWR5IHRvIGtlZXAgaW4gbWluZDogCgoxLiBUaGUgZGF0YSBkbyBub3QgaW5jbHVkZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29tcG9zaXRpb24gb2YgcGFydGljdWxhdGUgbWF0dGVyLiBEaWZmZXJlbnQgdHlwZXMgb2YgcGFydGljdWxhdGVzIG1heSBiZSBtb3JlIGJlbmlnbiBvciBkZWxldGVyaW91cyBmb3IgaGVhbHRoIG91dGNvbWVzLgoKMi4gT3V0ZG9vciBwb2xsdXRpb24gbGV2ZWxzIGFyZSBub3QgbmVjZXNzYXJpbHkgYW4gaW5kaWNhdGlvbiBvZiBpbmRpdmlkdWFsIGV4cG9zdXJlcy4gUGVvcGxlIHNwZW5kIGRpZmZlcmluZyBhbW91bnRzIG9mIHRpbWUgaW5kb29ycyBhbmQgb3V0ZG9vcnMgYW5kIGFyZSBleHBvc2VkIHRvIGRpZmZlcmVudCBwb2xsdXRpb24gbGV2ZWxzIGluZG9vcnMuIFJlc2VhcmNoZXJzIGFyZSBub3cgZGV2ZWxvcGluZyBwZXJzb25hbCBtb25pdG9yaW5nIHN5c3RlbXMgdG8gdHJhY2sgYWlyIHBvbGx1dGlvbiBsZXZlbHMgb24gdGhlIHBlcnNvbmFsIGxldmVsLgoKMy4gT3VyIGFuYWx5c2lzIHdpbGwgdXNlIGFubnVhbCBtZWFuIGVzdGltYXRlcyBvZiBwb2xsdXRpb24gbGV2ZWxzLCBidXQgdGhlc2UgY2FuIHZhcnkgZ3JlYXRseSBieSBzZWFzb24sIGRheSBhbmQgZXZlbiBob3VyLiBUaGVyZSBhcmUgZGF0YSBzb3VyY2VzIHRoYXQgaGF2ZSBmaW5lciBsZXZlbHMgb2YgdGVtcG9yYWwgZGF0YSwgaG93ZXZlciB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBsb25nIHRlcm0gZXhwb3N1cmVzLCBhcyB0aGVzZSBhcHBlYXIgdG8gYmUgdGhlIG1vc3QgaW5mbHVlbnRpYWwgZm9yIGhlYWx0aCBvdXRjb21lcywgc28gd2UgY2hvc2UgdG8gdXNlIGFubnVhbCBsZXZlbCBkYXRhLiAKCgojICoqV2hhdCBhcmUgdGhlIGRhdGE/KiogeyN3aGF0YXJldGhlZGF0YX0KKioqCgpXaGVuIHVzaW5nIG1hY2hpbmUgbGVhcm5pbmcgZm9yIHByZWRpY3Rpb24sIHRoZXJlIGFyZSB0d28gbWFpbiB0eXBlcyBvZiBkYXRhIG9mIGludGVyZXN0OgoKMS4gQW4gKipjb250aW51b3VzKiogb3V0Y29tZSB2YXJpYWJsZSB0aGF0IHdlIHdhbnQgdG8gcHJlZGljdCAKMi4gQSBzZXQgb2YgZmVhdHVyZShzKSAob3IgcHJlZGljdG9yIHZhcmlhYmxlcykgdGhhdCB3ZSB1c2UgdG8gcHJlZGljdCB0aGUgb3V0Y29tZSB2YXJpYWJsZQoKVGhlICoqb3V0Y29tZSB2YXJpYWJsZSoqIGlzIHdoYXQgYXJlIHRyeWluZyB0byAqKnByZWRpY3QqKi4gClRvIGJ1aWxkIChvciB0cmFpbikgb3VyIG1vZGVsLCB3ZSB1c2UgYm90aCB0aGUgb3V0Y29tZSBhbmQgZmVhdHVyZXMuClRoZSBnb2FsIGlzIHRvIGlkZW50aWZ5IGluZm9ybWF0aXZlIGZlYXR1cmVzIHRoYXQgY2FuIGV4cGxhaW4gYSBsYXJnZSBhbW91bnQgb2YgdmFyaWF0aW9uIGluIG91ciBvdXRjb21lIHZhcmlhYmxlLiAKVXNpbmcgdGhpcyBtb2RlbCwgd2UgY2FuIHRoZW4gcHJlZGljdCB0aGUgb3V0Y29tZSBmcm9tIG5ldyBvYnNlcnZhdGlvbnMgd2l0aCB0aGUgc2FtZSBmZWF0dXJlcyB3aGVyZSBoYXZlIG5vdCBvYnNlcnZlZCB0aGUgb3V0Y29tZS4gCgpBcyBhIHNpbXBsZSBleGFtcGxlLCBpbWFnaW5lIHRoYXQgd2UgaGF2ZSBkYXRhIGFib3V0IHRoZSBzYWxlcyBhbmQgY2hhcmFjdGVyaXN0aWNzIG9mIGNhcnMgZnJvbSBsYXN0IHllYXIgYW5kIHdlIHdhbnQgdG8gcHJlZGljdCB3aGljaCBjYXJzIG1pZ2h0IHNlbGwgd2VsbCB0aGlzIHllYXIuIApXZSBkbyBub3QgaGF2ZSB0aGUgc2FsZXMgZGF0YSB5ZXQgZm9yIHRoaXMgeWVhciwgYnV0IHdlIGRvIGtub3cgdGhlIGNoYXJhY3RlcmlzdGljcyBvZiBvdXIgY2FycyBmb3IgdGhpcyB5ZWFyLiAKV2UgY2FuIGJ1aWxkIGEgbW9kZWwgb2YgdGhlIGNoYXJhY3RlcmlzdGljcyB0aGF0IGV4cGxhaW5lZCBzYWxlcyBsYXN0IHllYXIgdG8gZXN0aW1hdGUgd2hhdCBjYXJzIG1pZ2h0IHNlbGwgd2VsbCB0aGlzIHllYXIuIApJbiB0aGlzIGNhc2UsIG91ciBvdXRjb21lIHZhcmlhYmxlIGlzIHRoZSBzYWxlcyBvZiBjYXJzLCB3aGlsZSB0aGUgZGlmZmVyZW50IGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgY2FycyBtYWtlIHVwIG91ciBmZWF0dXJlcy4KCiMjIyAqKlN0YXJ0IHdpdGggYSBxdWVzdGlvbioqCioqKgoKVGhpcyBpcyB0aGUgbW9zdCBjb21tb25seSBtaXNzZWQgc3RlcCB3aGVuIGRldmVsb3BpbmcgYSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobS4gCk1hY2hpbmUgbGVhcm5pbmcgY2FuIHZlcnkgZWFzaWx5IGJlIHR1cm5lZCBpbnRvIGFuIGVuZ2luZWVyaW5nIHByb2JsZW0uIApKdXN0IGR1bXAgdGhlIG91dGNvbWUgYW5kIHRoZSBmZWF0dXJlcyBpbnRvIGEgYmxhY2sgYm94IGFsZ29yaXRobSBhbmQgdmlvbGEhIApCdXQgdGhpcyBraW5kIG9mIHRoaW5raW5nIGNhbiBsZWFkIHRvIG1ham9yIHByb2JsZW1zLiBJbiBnZW5lcmFsIGdvb2QgbWFjaGluZSBsZWFybmluZyBxdWVzdGlvbnM6CgoxLiBIYXZlIGEgcGxhdXNpYmxlIGV4cGxhbmF0aW9uIGZvciB3aHkgdGhlIGZlYXR1cmVzIHByZWRpY3QgdGhlIG91dGNvbWUuIAoyLiBDb25zaWRlciBwb3RlbnRpYWwgdmFyaWF0aW9uIGluIGJvdGggdGhlIGZlYXR1cmVzIGFuZCB0aGUgb3V0Y29tZSBvdmVyIHRpbWUKMy4gQXJlIGNvbnNpc3RlbnRseSByZS1ldmFsdWF0ZWQgb24gY3JpdGVyaWEgMSBhbmQgMiBvdmVyIHRpbWUuIAoKSW4gdGhpcyBjYXNlIHN0dWR5LCB3ZSB3YW50IHRvICoqcHJlZGljdCoqIGFpciBwb2xsdXRpb24gbGV2ZWxzLiAKVG8gYnVpbGQgdGhpcyBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobSwgb3VyICoqb3V0Y29tZSB2YXJpYWJsZSoqIGlzIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIChQTX4yLjV+KSBjYXB0dXJlZCBmcm9tIGFpciBwb2xsdXRpb24gbW9uaXRvcnMgaW4gdGhlIGNvbnRpZ3VvdXMgVVMgZnJvbSAyMDA4LiAKT3VyICoqZmVhdHVyZXMqKiAob3IgcHJlZGljdG9yIHZhcmlhYmxlcykgaW5jbHVkZSBkYXRhIGFib3V0IHBvcHVsYXRpb24gZGVuc2l0eSwgcm9hZCBkZW5zaXR5LCB1cmJhbml6YXRpb24gbGV2ZWxzLCBhbmQgTkFTQSBzYXRlbGxpdGUgZGF0YS4gCgpBbGwgb2Ygb3VyIGRhdGEgd2FzIHByZXZpb3VzbHkgY29sbGVjdGVkIGJ5IGEgW3Jlc2VhcmNoZXJdKGh0dHA6Ly93d3cuYmlvc3RhdC5qaHNwaC5lZHUvfnJwZW5nLykgYXQgdGhlIFtKb2hucyBIb3BraW5zIFNjaG9vbCBvZiBQdWJsaWMgSGVhbHRoXShodHRwczovL3d3dy5qaHNwaC5lZHUvKSB3aG8gc3R1ZGllcyBhaXIgcG9sbHV0aW9uIGFuZCBjbGltYXRlIGNoYW5nZS4gCgoKIyMjICoqT3VyIG91dGNvbWUgdmFyaWFibGUqKgoqKioKClRoZSBtb25pdG9yIGRhdGEgdGhhdCB3ZSB3aWxsIGJlIHVzaW5nIGNvbWVzIGZyb20gKipbZ3JhdmltZXRyaWMgbW9uaXRvcnNdKGh0dHBzOi8vcHVibGljbGFiLm9yZy93aWtpL2ZpbHRlci1wbSl7dGFyZ2V0PSJfYmxhbmsifSoqIChzZWUgcGljdHVyZSBiZWxvdykgb3BlcmF0ZWQgYnkgdGhlIFVTIFtFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpXShodHRwczovL3d3dy5lcGEuZ292Lyl7dGFyZ2V0PSJfYmxhbmsifS4KCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0iMTAwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCJtb25pdG9yLnBuZyIpKQpgYGAKCiMjIyMjIFtpbWFnZSBjdXJ0ZXN5IG9mIFtLaXJzdGVuIEtvZWhsZXJdKGh0dHBzOi8vd3d3Lmpoc3BoLmVkdS9mYWN1bHR5L2RpcmVjdG9yeS9wcm9maWxlLzI5Mjgva2lyc3Rlbi1rb2VobGVyKV0KClRoZXNlIG1vbml0b3JzIHVzZSBhIGZpbHRyYXRpb24gc3lzdGVtIHRvIHNwZWNpZmljYWxseSBjYXB0dXJlIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyLiAKCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aD0iMTUwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCJmaWx0ZXIucG5nIikpCmBgYAoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL3B1YmxpY2xhYi5vcmcvd2lraS9maWx0ZXItcG0pe3RhcmdldD0iX2JsYW5rIn0KClRoZSB3ZWlnaHQgb2YgdGhpcyBwYXJ0aWN1bGF0ZSBtYXR0ZXIgaXMgbWFudWFsbHkgbWVhc3VyZWQgZGFpbHkgb3Igd2Vla2x5LiAKRm9yIHRoZSBFUEEgc3RhbmRhcmQgb3BlcmF0aW5nIHByb2NlZHVyZSBmb3IgUE0gZ3JhdmltZXRyaWMgYW5hbHlzaXMgaW4gMjAwOCwgd2UgcmVmZXIgdGhlIHJlYWRlciB0byBbaGVyZV0oaHR0cHM6Ly93d3czLmVwYS5nb3YvdHRuYW10aTEvZmlsZXMvYW1iaWVudC9wbTI1L3NwZWMvUlRJR3Jhdk1hc3NTT1BGSU5BTC5wZGYpe3RhcmdldD0iX2JsYW5rIn0uCgo8ZGV0YWlscz48c3VtbWFyeT5Gb3IgbW9yZSBvbiBHcmF2aW1ldHJpYyBhbmFseXNpcywgeW91IGNhbiBleHBhbmQgaGVyZSA8L3N1bW1hcnk+CgpHcmF2aW1ldHJpYyBhbmFseXNpcyBpcyBhbHNvIHVzZWQgZm9yIFtlbWlzc2lvbiB0ZXN0aW5nXShodHRwczovL3d3dy5tdC5jb20vdXMvZW4vaG9tZS9hcHBsaWNhdGlvbnMvTGFib3JhdG9yeV93ZWlnaGluZy9lbWlzc2lvbnMtdGVzdGluZy1wYXJ0aWN1bGF0ZS1tYXR0ZXIuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifS4gClRoZSBzYW1lIGlkZWEgYXBwbGllczogYSBmcmVzaCBmaWx0ZXIgaXMgYXBwbGllZCBhbmQgdGhlIGRlc2lyZWQgYW1vdW50IG9mIHRpbWUgcGFzc2VzLCB0aGVuIHRoZSBmaWx0ZXIgaXMgcmVtb3ZlZCBhbmQgd2VpZ2hlZC4gCgpUaGVyZSBhcmUgW290aGVyIG1vbml0b3Jpbmcgc3lzdGVtc10oaHR0cHM6Ly93d3cuc2Vuc2lyaW9uLmNvbS9lbi9hYm91dC11cy9uZXdzcm9vbS9zZW5zaXJpb24tc3BlY2lhbGlzdC1hcnRpY2xlcy9wYXJ0aWN1bGF0ZS1tYXR0ZXItc2Vuc2luZy1mb3ItYWlyLXF1YWxpdHktbWVhc3VyZW1lbnRzLyl7dGFyZ2V0PSJfYmxhbmsifSB0aGF0IGNhbiBwcm92aWRlIGhvdXJseSBtZWFzdXJlbWVudHMsIGJ1dCB3ZSB3aWxsIG5vdCBiZSB1c2luZyBkYXRhIGZyb20gdGhlc2UgbW9uaXRvcnMgaW4gb3VyIGFuYWx5c2lzLiAKR3JhdmltZXRyaWMgYW5hbHlzaXMgaXMgY29uc2lkZXJlZCB0byBiZSBhbW9uZyB0aGUgbW9zdCBhY2N1cmF0ZSBtZXRob2RzIGZvciBtZWFzdXJpbmcgcGFydGljdWxhdGUgbWF0dGVyLgoKPC9kZXRhaWxzPgoKSW4gb3VyIGRhdGEgc2V0LCB0aGUgYHZhbHVlYCBjb2x1bW4gaW5kaWNhdGVzIHRoZSBQTX4yLjV+IG1vbml0b3IgYXZlcmFnZSBmb3IgMjAwOCBpbiBtYXNzIG9mIGZpbmUgcGFydGljbGVzL3ZvbHVtZSBvZiBhaXIgZm9yIDg3NiBncmF2aW1ldHJpYyBtb25pdG9ycy4gClRoZSB1bml0cyBhcmUgbWljcm9ncmFtcyBvZiBmaW5lIHBhcnRpY3VsYXRlIG1hdHRlciAoUE0pIHRoYXQgaXMgbGVzcyB0aGFuIDIuNSBtaWNyb21ldGVycyBpbiBkaWFtZXRlciBwZXIgY3ViaWMgbWV0ZXIgb2YgYWlyIC0gbWFzcyBjb25jZW50cmF0aW9uICh1Zy9tXjNeKS4KUmVjYWxsIHRoZSBXSE8gZXhwb3N1cmUgZ3VpZGVsaW5lIGlzIDwgMTAgdWcvbV4zXiBvbiBhdmVyYWdlIGFubnVhbGx5IGZvciBQTX4yLjV+LgoKIyMjICoqT3VyIGZlYXR1cmVzIChwcmVkaWN0b3IgdmFyaWFibGVzKSoqCioqKgoKVGhlcmUgYXJlIDQ4IGZlYXR1cmVzIHdpdGggdmFsdWVzIGZvciBlYWNoIG9mIHRoZSA4NzYgbW9uaXRvcnMgKG9ic2VydmF0aW9ucykuIApUaGUgZGF0YSBjb21lcyBmcm9tIHRoZSBVUyBbRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKV0oaHR0cHM6Ly93d3cuZXBhLmdvdi8pe3RhcmdldD0iX2JsYW5rIn0sIHRoZSBbTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFkbWluaXN0cmF0aW9uIChOQVNBKV0oaHR0cHM6Ly93d3cubmFzYS5nb3YvKXt0YXJnZXQ9Il9ibGFuayJ9LCB0aGUgVVMgW0NlbnN1c10oaHR0cHM6Ly93d3cuY2Vuc3VzLmdvdi9hYm91dC93aGF0L2NlbnN1cy1hdC1hLWdsYW5jZS5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9LCBhbmQgdGhlIFtOYXRpb25hbCBDZW50ZXIgZm9yIEhlYWx0aCBTdGF0aXN0aWNzIChOQ0hTKV0oaHR0cHM6Ly93d3cuY2RjLmdvdi9uY2hzL2Fib3V0L2luZGV4Lmh0bSl7dGFyZ2V0PSJfYmxhbmsifS4KCjxkZXRhaWxzPjxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHNlZSBhIHRhYmxlIGFib3V0IHRoZSBzZXQgb2YgZmVhdHVyZXMgPC9zdW1tYXJ5PgoKVmFyaWFibGUgICB8IERldGFpbHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLS0tLS0tLS0tLSB8LS0tLS0tLS0tLS0tLQoqKmlkKiogIHwgTW9uaXRvciBudW1iZXIgIDxicj4gLS0gdGhlIGNvdW50eSBudW1iZXIgaXMgaW5kaWNhdGVkIGJlZm9yZSB0aGUgZGVjaW1hbCA8YnI+IC0tIHRoZSBtb25pdG9yIG51bWJlciBpcyBpbmRpY2F0ZWQgYWZ0ZXIgdGhlIGRlY2ltYWwgPGJyPiAgKipFeGFtcGxlKio6IDEwNzMuMDAyMyAgaXMgSmVmZmVyc29uIGNvdW50eSAoMTA3MykgYW5kIC4wMDIzIG9uZSBvZiA4IG1vbml0b3JzIAoqKmZpcHMqKiB8IEZlZGVyYWwgaW5mb3JtYXRpb24gcHJvY2Vzc2luZyBzdGFuZGFyZCBudW1iZXIgZm9yIHRoZSBjb3VudHkgd2hlcmUgdGhlIG1vbml0b3IgaXMgbG9jYXRlZCA8YnI+IC0tIDUgZGlnaXQgaWQgY29kZSBmb3IgY291bnRpZXMgKHplcm8gaXMgb2Z0ZW4gdGhlIGZpcnN0IHZhbHVlIGFuZCBzb21ldGltZXMgaXMgbm90IHNob3duKSA8YnI+IC0tIHRoZSBmaXJzdCAyIG51bWJlcnMgaW5kaWNhdGUgdGhlIHN0YXRlIDxicj4gLS0gdGhlIGxhc3QgdGhyZWUgbnVtYmVycyBpbmRpY2F0ZSB0aGUgY291bnR5IDxicj4gICoqRXhhbXBsZSoqOiBBbGFiYW1hJ3Mgc3RhdGUgY29kZSBpcyAwMSBiZWNhdXNlIGl0IGlzIGZpcnN0IGFscGhhYmV0aWNhbGx5IDxicj4gKG5vdGU6IEFsYXNrYSBhbmQgSGF3YWlpIGFyZSBub3QgaW5jbHVkZWQgYmVjYXVzZSB0aGV5IGFyZSBub3QgcGFydCBvZiB0aGUgY29udGlndW91cyBVUykgIAoqKkxhdCoqIHwgTGF0aXR1ZGUgb2YgdGhlIG1vbml0b3IgaW4gZGVncmVlcyAgCioqTG9uKiogfCBMb25naXR1ZGUgb2YgdGhlIG1vbml0b3IgaW4gZGVncmVlcyAgCioqc3RhdGUqKiB8IFN0YXRlIHdoZXJlIHRoZSBtb25pdG9yIGlzIGxvY2F0ZWQKKipjb3VudHkqKiB8IENvdW50eSB3aGVyZSB0aGUgbW9uaXRvciBpcyBsb2NhdGVkCioqY2l0eSoqIHwgQ2l0eSB3aGVyZSB0aGUgbW9uaXRvciBpcyBsb2NhdGVkCioqQ01BUSoqICB8IEVzdGltYXRlZCB2YWx1ZXMgb2YgYWlyIHBvbGx1dGlvbiBmcm9tIGEgY29tcHV0YXRpb25hbCBtb2RlbCBjYWxsZWQgWyoqQ29tbXVuaXR5IE11bHRpc2NhbGUgQWlyIFF1YWxpdHkgKENNQVEpKipdKGh0dHBzOi8vd3d3LmVwYS5nb3YvY21hcSl7dGFyZ2V0PSJfYmxhbmsifSA8YnI+IC0tICBBIG1vbml0b3Jpbmcgc3lzdGVtIHRoYXQgc2ltdWxhdGVzIHRoZSBwaHlzaWNzIG9mIHRoZSBhdG1vc3BoZXJlIHVzaW5nIGNoZW1pc3RyeSBhbmQgd2VhdGhlciBkYXRhIHRvIHByZWRpY3QgdGhlIGFpciBwb2xsdXRpb24gPGJyPiAtLSAqKipEb2VzIG5vdCB1c2UgYW55IG9mIHRoZSBQTX4yLjV+IGdyYXZpbWV0cmljIG1vbml0b3JpbmcgZGF0YS4qKiogKFRoZXJlIGlzIGEgdmVyc2lvbiB0aGF0IGRvZXMgdXNlIHRoZSBncmF2aW1ldHJpYyBtb25pdG9yaW5nIGRhdGEsIGJ1dCBub3QgdGhpcyBvbmUhKSA8YnI+IC0tIERhdGEgZnJvbSB0aGUgRVBBCioqemN0YSoqIHwgW1ppcCBDb2RlIFRhYnVsYXRpb24gQXJlYV0oaHR0cHM6Ly93d3cyLmNlbnN1cy5nb3YvZ2VvL3BkZnMvZWR1Y2F0aW9uL2Jyb2NodXJlcy9aQ1RBcy5wZGYpe3RhcmdldD0iX2JsYW5rIn0gd2hlcmUgdGhlIG1vbml0b3IgaXMgbG9jYXRlZCA8YnI+IC0tIFBvc3RhbCBaaXAgY29kZXMgYXJlIGNvbnZlcnRlZCBpbnRvICJnZW5lcmFsaXplZCBhcmVhbCByZXByZXNlbnRhdGlvbnMiIHRoYXQgYXJlIG5vbi1vdmVybGFwcGluZyAgPGJyPiAtLSBEYXRhIGZyb20gdGhlIDIwMTAgQ2Vuc3VzICAKKip6Y3RhX2FyZWEqKiB8IExhbmQgYXJlYSBvZiB0aGUgemlwIGNvZGUgYXJlYSBpbiBtZXRlcnMgc3F1YXJlZCAgPGJyPiAtLSBEYXRhIGZyb20gdGhlIDIwMTAgQ2Vuc3VzICAKKip6Y3RhX3BvcCoqIHwgUG9wdWxhdGlvbiBpbiB0aGUgemlwIGNvZGUgYXJlYSAgPGJyPiAtLSBEYXRhIGZyb20gdGhlIDIwMTAgQ2Vuc3VzICAKKippbXBfYTUwMCoqIHwgSW1wZXJ2aW91cyBzdXJmYWNlIG1lYXN1cmUgPGJyPiAtLSBXaXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiA1MDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciA8YnI+IC0tIEltcGVydmlvdXMgc3VyZmFjZSBhcmUgcm9hZHMsIGNvbmNyZXRlLCBwYXJraW5nIGxvdHMsIGJ1aWxkaW5ncyA8YnI+IC0tIFRoaXMgaXMgYSBtZWFzdXJlIG9mIGRldmVsb3BtZW50IAoqKmltcF9hMTAwMCoqIHwgSW1wZXJ2aW91cyBzdXJmYWNlIG1lYXN1cmUgPGJyPiAtLSAgV2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTAwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yCioqaW1wX2E1MDAwKiogfCBJbXBlcnZpb3VzIHN1cmZhY2UgbWVhc3VyZSA8YnI+IC0tICBXaXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiA1MDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgIAoqKmltcF9hMTAwMDAqKiB8IEltcGVydmlvdXMgc3VyZmFjZSBtZWFzdXJlIDxicj4gLS0gIFdpdGhpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDEwMDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgICAKKippbXBfYTE1MDAwKiogfCBJbXBlcnZpb3VzIHN1cmZhY2UgbWVhc3VyZSA8YnI+IC0tICBXaXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAxNTAwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yICAKKipjb3VudHlfYXJlYSoqIHwgTGFuZCBhcmVhIG9mIHRoZSBjb3VudHkgb2YgdGhlIG1vbml0b3IgaW4gbWV0ZXJzIHNxdWFyZWQgIAoqKmNvdW50eV9wb3AqKiB8IFBvcHVsYXRpb24gb2YgdGhlIGNvdW50eSBvZiB0aGUgbW9uaXRvciAgCioqTG9nX2Rpc3RfdG9fcHJpc2VjKiogfCBMb2cgKE5hdHVyYWwgbG9nKSBkaXN0YW5jZSB0byBhIHByaW1hcnkgb3Igc2Vjb25kYXJ5IHJvYWQgZnJvbSB0aGUgbW9uaXRvciA8YnI+IC0tIEhpZ2h3YXkgb3IgbWFqb3Igcm9hZCAgCioqbG9nX3ByaV9sZW5ndGhfNTAwMCoqIHwgQ291bnQgb2YgcHJpbWFyeSByb2FkIGxlbmd0aCBpbiBtZXRlcnMgaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiA1MDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSA8YnI+IC0tIEhpZ2h3YXlzIG9ubHkgIAoqKmxvZ19wcmlfbGVuZ3RoXzEwMDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IHJvYWQgbGVuZ3RoIGluIG1ldGVycyBpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDEwMDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSA8YnI+IC0tIEhpZ2h3YXlzIG9ubHkgIAoqKmxvZ19wcmlfbGVuZ3RoXzE1MDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IHJvYWQgbGVuZ3RoIGluIG1ldGVycyBpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDE1MDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSA8YnI+IC0tIEhpZ2h3YXlzIG9ubHkgIAoqKmxvZ19wcmlfbGVuZ3RoXzI1MDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IHJvYWQgbGVuZ3RoIGluIG1ldGVycyBpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDI1MDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSA8YnI+IC0tIEhpZ2h3YXlzIG9ubHkgIAoqKmxvZ19wcmlzZWNfbGVuZ3RoXzUwMCoqIHwgQ291bnQgb2YgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHJvYWQgbGVuZ3RoIGluIG1ldGVycyBpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDUwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgIDxicj4gLS0gSGlnaHdheSBhbmQgc2Vjb25kYXJ5IHJvYWRzICAKKipsb2dfcHJpc2VjX2xlbmd0aF8xMDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTAwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgIDxicj4gLS0gSGlnaHdheSBhbmQgc2Vjb25kYXJ5IHJvYWRzICAKKipsb2dfcHJpc2VjX2xlbmd0aF81MDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgNTAwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgIDxicj4gLS0gSGlnaHdheSBhbmQgc2Vjb25kYXJ5IHJvYWRzICAKKipsb2dfcHJpc2VjX2xlbmd0aF8xMDAwMCoqIHwgQ291bnQgb2YgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHJvYWQgbGVuZ3RoIGluIG1ldGVycyBpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDEwMDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSAgPGJyPiAtLSBIaWdod2F5IGFuZCBzZWNvbmRhcnkgcm9hZHMgIAoqKmxvZ19wcmlzZWNfbGVuZ3RoXzE1MDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTUwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICA8YnI+IC0tIEhpZ2h3YXkgYW5kIHNlY29uZGFyeSByb2FkcyAgCioqbG9nX3ByaXNlY19sZW5ndGhfMjUwMDAqKiB8IENvdW50IG9mIHByaW1hcnkgYW5kIHNlY29uZGFyeSByb2FkIGxlbmd0aCBpbiBtZXRlcnMgaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAyNTAwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgIDxicj4gLS0gSGlnaHdheSBhbmQgc2Vjb25kYXJ5IHJvYWRzICAgICAgCioqbG9nX25laV8yMDA4X3BtMjVfc3VtXzEwMDAwKiogfCBUb25zIG9mIGVtaXNzaW9ucyBmcm9tIG1ham9yIHNvdXJjZXMgZGF0YSBiYXNlIChhbm51YWwgZGF0YSkgc3VtIG9mIGFsbCBzb3VyY2VzIHdpdGhpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDEwMDAwIG1ldGVycyBvZiBkaXN0YW5jZSBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSAgICAKKipsb2dfbmVpXzIwMDhfcG0yNV9zdW1fMTUwMDAqKiB8IFRvbnMgb2YgZW1pc3Npb25zIGZyb20gbWFqb3Igc291cmNlcyBkYXRhIGJhc2UgKGFubnVhbCBkYXRhKSBzdW0gb2YgYWxsIHNvdXJjZXMgd2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTUwMDAgbWV0ZXJzIG9mIGRpc3RhbmNlIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICAgICAKKipsb2dfbmVpXzIwMDhfcG0yNV9zdW1fMjUwMDAqKiB8IFRvbnMgb2YgZW1pc3Npb25zIGZyb20gbWFqb3Igc291cmNlcyBkYXRhIGJhc2UgKGFubnVhbCBkYXRhKSBzdW0gb2YgYWxsIHNvdXJjZXMgd2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMjUwMDAgbWV0ZXJzIG9mIGRpc3RhbmNlIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICAgICAKKipsb2dfbmVpXzIwMDhfcG0xMF9zdW1fMTAwMDAqKiB8IFRvbnMgb2YgZW1pc3Npb25zIGZyb20gbWFqb3Igc291cmNlcyBkYXRhIGJhc2UgKGFubnVhbCBkYXRhKSBzdW0gb2YgYWxsIHNvdXJjZXMgd2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTAwMDAgbWV0ZXJzIG9mIGRpc3RhbmNlIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICAgICAgCioqbG9nX25laV8yMDA4X3BtMTBfc3VtXzE1MDAwKip8IFRvbnMgb2YgZW1pc3Npb25zIGZyb20gbWFqb3Igc291cmNlcyBkYXRhIGJhc2UgKGFubnVhbCBkYXRhKSBzdW0gb2YgYWxsIHNvdXJjZXMgd2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTUwMDAgbWV0ZXJzIG9mIGRpc3RhbmNlIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICAgICAgCioqbG9nX25laV8yMDA4X3BtMTBfc3VtXzI1MDAwKiogfCBUb25zIG9mIGVtaXNzaW9ucyBmcm9tIG1ham9yIHNvdXJjZXMgZGF0YSBiYXNlIChhbm51YWwgZGF0YSkgc3VtIG9mIGFsbCBzb3VyY2VzIHdpdGhpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDI1MDAwIG1ldGVycyBvZiBkaXN0YW5jZSBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSAgICAgIAoqKnBvcGRlbnNfY291bnR5KiogfCBQb3B1bGF0aW9uIGRlbnNpdHkgKG51bWJlciBvZiBwZW9wbGUgcGVyIGtpbG9tZXRlciBzcXVhcmVkIGFyZWEgb2YgdGhlIGNvdW50eSkKKipwb3BkZW5zX3pjdGEqKiB8IFBvcHVsYXRpb24gZGVuc2l0eSAobnVtYmVyIG9mIHBlb3BsZSBwZXIga2lsb21ldGVyIHNxdWFyZWQgYXJlYSBvZiB6Y3RhKQoqKm5vaHMqKiB8IFBlcmNlbnRhZ2Ugb2YgcGVvcGxlIGluIHpjdGEgYXJlYSB3aGVyZSB0aGUgbW9uaXRvciBpcyB0aGF0ICoqZG8gbm90IGhhdmUgYSBoaWdoIHNjaG9vbCBkZWdyZWUqKiA8YnI+IC0tIERhdGEgZnJvbSB0aGUgQ2Vuc3VzCioqc29tZWhzKiogfCBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3Igd2hvc2UgaGlnaGVzdCBmb3JtYWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCB3YXMgKipzb21lIGhpZ2ggc2Nob29sIGVkdWNhdGlvbioqIDxicj4gLS0gRGF0YSBmcm9tIHRoZSBDZW5zdXMKKipocyoqIHwgUGVyY2VudGFnZSBvZiBwZW9wbGUgaW4gemN0YSBhcmVhIHdoZXJlIHRoZSBtb25pdG9yIHdob3NlIGhpZ2hlc3QgZm9ybWFsIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQgd2FzIGNvbXBsZXRpbmcgYSAqKmhpZ2ggc2Nob29sIGRlZ3JlZSoqIDxicj4gLS0gRGF0YSBmcm9tIHRoZSBDZW5zdXMgIAoqKnNvbWVjb2xsZWdlKiogfCBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3Igd2hvc2UgaGlnaGVzdCBmb3JtYWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCB3YXMgY29tcGxldGluZyAqKnNvbWUgY29sbGVnZSBlZHVjYXRpb24qKiA8YnI+IC0tIERhdGEgZnJvbSB0aGUgQ2Vuc3VzIAoqKmFzc29jaWF0ZSoqIHwgUGVyY2VudGFnZSBvZiBwZW9wbGUgaW4gemN0YSBhcmVhIHdoZXJlIHRoZSBtb25pdG9yIHdob3NlIGhpZ2hlc3QgZm9ybWFsIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQgd2FzIGNvbXBsZXRpbmcgYW4gKiphc3NvY2lhdGUgZGVncmVlKiogPGJyPiAtLSBEYXRhIGZyb20gdGhlIENlbnN1cyAKKipiYWNoZWxvcioqIHwgUGVyY2VudGFnZSBvZiBwZW9wbGUgaW4gemN0YSBhcmVhIHdoZXJlIHRoZSBtb25pdG9yIHdob3NlIGhpZ2hlc3QgZm9ybWFsIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQgd2FzIGEgKipiYWNoZWxvcidzIGRlZ3JlZSoqIDxicj4gLS0gRGF0YSBmcm9tIHRoZSBDZW5zdXMgCioqZ3JhZCoqIHwgUGVyY2VudGFnZSBvZiBwZW9wbGUgaW4gemN0YSBhcmVhIHdoZXJlIHRoZSBtb25pdG9yIHdob3NlIGhpZ2hlc3QgZm9ybWFsIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQgd2FzIGEgKipncmFkdWF0ZSBkZWdyZWUqKiA8YnI+IC0tIERhdGEgZnJvbSB0aGUgQ2Vuc3VzIAoqKnBvdioqIHwgUGVyY2VudGFnZSBvZiBwZW9wbGUgaW4gemN0YSBhcmVhIHdoZXJlIHRoZSBtb25pdG9yIGlzIHRoYXQgbGl2ZWQgaW4gWyoqcG92ZXJ0eSoqXShodHRwczovL2FzcGUuaGhzLmdvdi8yMDA4LWhocy1wb3ZlcnR5LWd1aWRlbGluZXMpIGluIDIwMDggLSBvciB3b3VsZCBpdCBoYXZlIGJlZW4gMjAwNyBndWlkZWxpbmVzPz9odHRwczovL2FzcGUuaGhzLmdvdi8yMDA3LWhocy1wb3ZlcnR5LWd1aWRlbGluZXMgPGJyPiAtLSBEYXRhIGZyb20gdGhlIENlbnN1cyAgCioqaHNfb3JsZXNzKiogfCAgUGVyY2VudGFnZSBvZiBwZW9wbGUgaW4gemN0YSBhcmVhIHdoZXJlIHRoZSBtb25pdG9yIHdob3NlIGhpZ2hlc3QgZm9ybWFsIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQgd2FzIGEgKipoaWdoIHNjaG9vbCBkZWdyZWUgb3IgbGVzcyoqIChzdW0gb2Ygbm9ocywgc29tZWhzLCBhbmQgaHMpICAKKip1cmMyMDEzKiogfCBbMjAxMyBVcmJhbi1ydXJhbCBjbGFzc2lmaWNhdGlvbl0oaHR0cHM6Ly93d3cuY2RjLmdvdi9uY2hzL2RhdGEvc2VyaWVzL3NyXzAyL3NyMDJfMTY2LnBkZil7dGFyZ2V0PSJfYmxhbmsifSBvZiB0aGUgY291bnR5IHdoZXJlIHRoZSBtb25pdG9yIGlzIGxvY2F0ZWQgPGJyPiAtLSA2IGNhdGVnb3J5IHZhcmlhYmxlIC0gMSBpcyB0b3RhbGx5IHVyYmFuIDYgaXMgY29tcGxldGVseSBydXJhbCA8YnI+ICAtLSBEYXRhIGZyb20gdGhlIFtOYXRpb25hbCBDZW50ZXIgZm9yIEhlYWx0aCBTdGF0aXN0aWNzXShodHRwczovL3d3dy5jZGMuZ292L25jaHMvaW5kZXguaHRtKXt0YXJnZXQ9Il9ibGFuayJ9ICAgICAKKip1cmMyMDA2KiogfCBbMjAwNiBVcmJhbi1ydXJhbCBjbGFzc2lmaWNhdGlvbl0oaHR0cHM6Ly93d3cuY2RjLmdvdi9uY2hzL2RhdGEvc2VyaWVzL3NyXzAyL3NyMDJfMTU0LnBkZil7dGFyZ2V0PSJfYmxhbmsifSBvZiB0aGUgY291bnR5IHdoZXJlIHRoZSBtb25pdG9yIGlzIGxvY2F0ZWQgPGJyPiAtLSA2IGNhdGVnb3J5IHZhcmlhYmxlIC0gMSBpcyB0b3RhbGx5IHVyYmFuIDYgaXMgY29tcGxldGVseSBydXJhbCA8YnI+IC0tIERhdGEgZnJvbSB0aGUgW05hdGlvbmFsIENlbnRlciBmb3IgSGVhbHRoIFN0YXRpc3RpY3NdKGh0dHBzOi8vd3d3LmNkYy5nb3YvbmNocy9pbmRleC5odG0pe3RhcmdldD0iX2JsYW5rIn0gICAgIAoqKmFvZCoqIHwgQWVyb3NvbCBPcHRpY2FsIERlcHRoIG1lYXN1cmVtZW50IGZyb20gYSBOQVNBIHNhdGVsbGl0ZSA8YnI+IC0tIGJhc2VkIG9uIHRoZSBkaWZmcmFjdGlvbiBvZiBhIGxhc2VyIDxicj4gLS0gdXNlZCBhcyBhIHByb3h5IG9mIHBhcnRpY3VsYXRlIHBvbGx1dGlvbiA8YnI+IC0tIHVuaXQtbGVzcyAtIGhpZ2hlciB2YWx1ZSBpbmRpY2F0ZXMgbW9yZSBwb2xsdXRpb24gPGJyPiAtLSBEYXRhIGZyb20gTkFTQSAgCgo8L2RldGFpbHM+CgpNYW55IG9mIHRoZXNlIGZlYXR1cmVzIGhhdmUgdG8gZG8gd2l0aCB0aGUgY2lyY3VsYXIgYXJlYSBhcm91bmQgdGhlIG1vbml0b3IgY2FsbGVkIHRoZSAiYnVmZmVyIi4gVGhlc2UgYXJlIGlsbHVzdHJhdGVkIGluIHRoZSBmb2xsb3dpbmcgZmlndXJlOgoKYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoID0gIjgwMHB4Iix9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJyZWdyZXNzaW9uLnBuZyIpKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMTUyOTI5MDYpe3RhcmdldD0iX2JsYW5rIn0KCgoKIyAqKkRhdGEgSW1wb3J0KioKKioqCgpBbGwgb2Ygb3VyIGRhdGEgd2FzIHByZXZpb3VzbHkgY29sbGVjdGVkIGJ5IGEgW3Jlc2VhcmNoZXJdKGh0dHA6Ly93d3cuYmlvc3RhdC5qaHNwaC5lZHUvfnJwZW5nLykgYXQgdGhlIFtKb2hucyBIb3BraW5zIFNjaG9vbCBvZiBQdWJsaWMgSGVhbHRoXShodHRwczovL3d3dy5qaHNwaC5lZHUvKSB3aG8gc3R1ZGllcyBhaXIgcG9sbHV0aW9uIGFuZCBjbGltYXRlIGNoYW5nZS4gCgpXZSBoYXZlIG9uZSBDU1YgZmlsZSB0aGF0IGNvbnRhaW5zIGJvdGggb3VyIHNpbmdsZSAqKm91dGNvbWUgdmFyaWFibGUqKiBhbmQgYWxsIG9mIG91ciAqKmZlYXR1cmVzKiogKG9yIHByZWRpY3RvciB2YXJpYWJsZXMpLgoKTmV4dCwgd2UgaW1wb3J0IG91ciBkYXRhIGludG8gUiBub3cgc28gdGhhdCB3ZSBjYW4gZXhwbG9yZSB0aGUgZGF0YSBmdXJ0aGVyLiAKV2Ugd2lsbCBjYWxsIG91ciBkYXRhIG9iamVjdCBgcG1gIGZvciBwYXJ0aWN1bGF0ZSBtYXR0ZXIuIApXZSBpbXBvcnQgdGhlIGRhdGEgdXNpbmcgdGhlIGByZWFkX2NzdigpYCBmdW5jdGlvbiBmcm9tIHRoZSBgcmVhZHJgIHBhY2thZ2UuIApgYGB7cn0KcG0gPC0gcmVhZHI6OnJlYWRfY3N2KGhlcmUoImRvY3MiLCAicG0yNV9kYXRhLmNzdiIpKQpgYGAKCgoKIyAqKkRhdGEgRXhwbG9yYXRpb24gYW5kIFdyYW5nbGluZyoqCioqKgoKVGhlIGZpcnN0IHN0ZXAgaW4gcGVyZm9ybWluZyBhbnkgZGF0YSBhbmFseXNpcyBpcyB0byBleHBsb3JlIHRoZSBkYXRhLiAKCkZvciBleGFtcGxlLCB3ZSBtaWdodCB3YW50IHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSB2YXJpYWJsZXMgaW5jbHVkZWQgaW4gdGhlIGRhdGEsIGFzIHdlIG1heSBsZWFybiBhYm91dCBpbXBvcnRhbnQgZGV0YWlscyBhYm91dCB0aGUgZGF0YSB0aGF0IHdlIHNob3VsZCBrZWVwIGluIG1pbmQgYXMgd2UgdHJ5IHRvIHByZWRpY3Qgb3VyIG91dGNvbWUgdmFyaWFibGUuCgpGaXJzdCwgbGV0J3MganVzdCBnZXQgYSBnZW5lcmFsIHNlbnNlIG9mIG91ciBkYXRhLiAKV2UgY2FuIGRvIHRoYXQgdXNpbmcgdGhlIGBnbGltcHNlKClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2UgKGl0IGlzIGFsc28gaW4gdGhlIGB0aWJibGVgIHBhY2thZ2UpLgoKV2Ugd2lsbCBhbHNvIHVzZSB0aGUgYCU+JWAgcGlwZSwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gZGVmaW5lIHRoZSBpbnB1dCBmb3IgbGF0ZXIgc2VxdWVudGlhbCBzdGVwcy4gCgpUaGlzIHdpbGwgbWFrZSBtb3JlIHNlbnNlIHdoZW4gd2UgaGF2ZSBtdWx0aXBsZSBzZXF1ZW50aWFsIHN0ZXBzIHVzaW5nIHRoZSBzYW1lIGRhdGEgb2JqZWN0LiAKClRvIHVzZSB0aGUgcGlwZSBub3RhdGlvbiB3ZSBuZWVkIHRvIGluc3RhbGwgYW5kIGxvYWQgYGRwbHlyYCBhcyB3ZWxsLgoKRm9yIGV4YW1wbGUsIGhlcmUgd2Ugc3RhcnQgd2l0aCBgcG1gIGRhdGEgb2JqZWN0IGFuZCAicGlwZSIgdGhlIG9iamVjdCBpbnRvIGFzIGlucHV0IGludG8gdGhlIGBnbGltcHNlKClgIGZ1bmN0aW9uLiAKVGhlIG91dHB1dCBpcyBpcyBhbiBvdmVydmlldyBvZiB3aGF0IGlzIGluIHRoZSBgcG1gIG9iamVjdCBzdWNoIGFzIHRoZSBudW1iZXIgb2Ygcm93cyBhbmQgY29sdW1ucywgYWxsIHRoZSBjb2x1bW4gbmFtZXMsIHRoZSBkYXRhIHR5cGVzIGZvciBlYWNoIGNvbHVtbiBhbmQgdGhlIGZpcnN0IHZpZXcgdmFsdWVzIGluIGVhY2ggY29sdW1uLiAKVGhlIG91dHB1dCBiZWxvdyBpcyBzY3JvbGxhYmxlIHNvIHlvdSBjYW4gc2VlIGV2ZXJ5dGhpbmcgZnJvbSB0aGUgYGdsaW1wc2UoKWAgZnVuY3Rpb24uIAoKIyMjIyB7LnNjcm9sbGFibGUgfQoKYGBge3J9CiMgU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dCEKcG0gJT4lCiAgZHBseXI6OmdsaW1wc2UoKQpgYGAKCiMjIyMKCldlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgODc2IG1vbml0b3JzIChyb3dzKSBhbmQgdGhhdCB3ZSBoYXZlIDUwIHRvdGFsIHZhcmlhYmxlcyAoY29sdW1ucykgLSBvbmUgb2Ygd2hpY2ggaXMgdGhlIG91dGNvbWUgdmFyaWFibGUuIEluIHRoaXMgY2FzZSwgdGhlIG91dGNvbWUgdmFyaWFibGUgaXMgY2FsbGVkIGB2YWx1ZWAuIAoKTm90aWNlIHRoYXQgc29tZSBvZiB0aGUgdmFyaWFibGVzIHRoYXQgd2Ugd291bGQgdGhpbmsgb2YgYXMgZmFjdG9ycyAob3IgY2F0ZWdvcmljYWwgZGF0YSkgYXJlIGN1cnJlbnRseSBvZiBjbGFzcyBjaGFyYWN0ZXIgYXMgaW5kaWNhdGVkIGJ5IHRoZSBgPGNocj5gIGp1c3QgdG8gdGhlIHJpZ2h0IG9mIHRoZSBjb2x1bW4gbmFtZXMvdmFyaWFibGUgbmFtZXMgaW4gdGhlIGBnbGltcHNlKClgIG91dHB1dC4gVGhpcyBtZWFucyB0aGF0IHRoZSB2YXJpYWJsZSB2YWx1ZXMgYXJlIGNoYXJhY3RlciBzdHJpbmdzLCBzdWNoIGFzIHdvcmRzIG9yIHBocmFzZXMuIAoKVGhlIG90aGVyIHZhcmlhYmxlcyBhcmUgb2YgY2xhc3MgYDxkYmw+YCwgd2hpY2ggc3RhbmRzIGZvciBkb3VibGUgcHJlY2lzaW9uIHdoaWNoIGluZGljYXRlcyB0aGF0IHRoZSBhcmUgbnVtZXJpYyBhbmQgdGhhdCB0aGV5IGhhdmUgZGVjaW1hbCB2YWx1ZXMuIEluIGNvbnRyYXN0LCBvbmUgY291bGQgaGF2ZSBpbnRlZ2VyIHZhbHVlcyB3aGljaCB3b3VsZCBub3QgYWxsb3cgZm9yIGRlY2ltYWwgbnVtYmVycy4gSGVyZSBpcyBhIFtsaW5rXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Eb3VibGUtcHJlY2lzaW9uX2Zsb2F0aW5nLXBvaW50X2Zvcm1hdCl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBkb3VibGUgcHJlY2lzaW9uIG51bWVyaWMgdmFsdWVzLgoKQW5vdGhlciBjb21tb24gZGF0YSBjbGFzcyBpcyBmYWN0b3Igd2hpY2ggaXMgYWJicmV2aWF0ZWQgbGlrZSB0aGlzOiBgPGZjdD5gLiBBIGZhY3RvciBpcyBzb21ldGhpbmcgdGhhdCBoYXMgdW5pcXVlIGxldmVscyBidXQgdGhlcmUgaXMgbm8gYXBwcmVjaWFibGUgb3JkZXIgdG8gdGhlIGxldmVscy4gRm9yIGV4YW1wbGUgd2UgY2FuIGhhdmUgYSBudW1lcmljIHZhbHVlIHRoYXQgaXMganVzdCBhbiBpZCB0aGF0IHdlIHdhbnQgdG8gYmUgaW50ZXJwcmV0ZWQgYXMganVzdCBhIHVuaXF1ZSBsZXZlbCBhbmQgbm90IGFzIHRoZSBudW1iZXIgdGhhdCBpdCB3b3VsZCB0eXBpY2FsbHkgaW5kaWNhdGUuIFRoaXMgd291bGQgYmUgdXNlZnVsIGZvciBzZXZlcmFsIG9mIG91ciB2YXJpYWJsZXM6CgoxLiB0aGUgbW9uaXRvciBJRCAoYGlkYCkKMi4gdGhlIEZlZGVyYWwgSW5mb3JtYXRpb24gUHJvY2Vzc2luZyBTdGFuZGFyZCBudW1iZXIgZm9yIHRoZSBjb3VudHkgd2hlcmUgdGhlIG1vbml0b3Igd2FzIGxvY2F0ZWQgKGBmaXBzYCkKMy4gdGhlIHppcCBjb2RlIHRhYnVsYXRpb24gYXJlYSAoYHpjdGFgKQoKTm9uZSBvZiB0aGUgdmFsdWVzIGFjdHVhbGx5IGhhdmUgYW55IHJlYWwgbnVtZXJpYyBtZWFuaW5nLCBzbyB3ZSB3YW50IHRvIG1ha2Ugc3VyZSB0aGF0IFIgZG9lcyBub3QgaW50ZXJwcmV0IHRoZW0gYXMgaWYgdGhleSBkby4gCgpTbyBsZXQncyBjb252ZXJ0IHRoZXNlIHZhcmlhYmxlcyBpbnRvIGZhY3RvcnMuIApXZSBjYW4gZG8gdGhpcyB1c2luZyB0aGUgYGFjcm9zcygpYCBmdW5jdGlvbiBvZiB0aGUgYGRwbHlyYCBwYWNrYWdlIGFuZCB0aGUgYGFzLmZhY3RvcigpYCBiYXNlIGZ1bmN0aW9uLiAKVGhlIGBhY3Jvc3MoKWAgZnVuY3Rpb24gaGFzIHR3byBtYWluIGFyZ3VtZW50czogKGkpIHRoZSBjb2x1bW5zIHlvdSB3YW50IHRvIG9wZXJhdGUgb24gYW5kIChpaSkgdGhlIGZ1bmN0aW9uIG9yIGxpc3Qgb2YgZnVuY3Rpb25zIHRvIGFwcGx5IHRvIGVhY2ggY29sdW1uLiAKCkluIHRoaXMgY2FzZSwgd2UgYXJlIGFsc28gdXNpbmcgdGhlIGBtYWdyaXR0cmAgYXNzaWdubWVudCBwaXBlIG9yIGRvdWJsZSBwaXBlIHRoYXQgbG9va3MgbGlrZSB0aGlzIGAlPD4lYCBvZiB0aGUgYG1hZ3JpdHRyYCBwYWNrYWdlLiAKVGhpcyBhbGxvd3MgdXMgdXNlIHRoZSBgcG1gIGRhdGEgYXMgaW5wdXQsIGJ1dCBhbHNvIHJlYXNzaWducyB0aGUgb3V0cHV0IHRvIHRoZSBzYW1lIGRhdGEgb2JqZWN0IG5hbWUuCgojIyMjIHsuc2Nyb2xsYWJsZSB9CgpgYGB7cn0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpwbSAlPD4lCiAgbXV0YXRlKGFjcm9zcyhjKGlkLCBmaXBzLCB6Y3RhKSwgYXMuZmFjdG9yKSkgCgpnbGltcHNlKHBtKQpgYGAKCiMjIyMKCkdyZWF0ISBOb3cgd2UgY2FuIHNlZSB0aGF0IHRoZXNlIHZhcmlhYmxlcyBhcmUgbm93IGZhY3RvcnMgYXMgaW5kaWNhdGVkIGJ5IGA8ZmN0PmAgYWZ0ZXIgdGhlIHZhcmlhYmxlIG5hbWUuCgoKCiMjIyAqKmBza2ltYCBwYWNrYWdlKioKKioqCgpUaGUgYHNraW0oKWAgZnVuY3Rpb24gb2YgdGhlIGBza2ltcmAgcGFja2FnZSBpcyBhbHNvIHJlYWxseSBoZWxwZnVsIGZvciBnZXR0aW5nIGEgZ2VuZXJhbCBzZW5zZSBvZiB5b3VyIGRhdGEuCkJ5IGRlc2lnbiwgaXQgcHJvdmlkZXMgc3VtbWFyeSBzdGF0aXN0aWNzIGFib3V0IHZhcmlhYmxlcyBpbiB0aGUgZGF0YSBzZXQuIAoKCiMjIyMgey5zY3JvbGxhYmxlIH0KCmBgYHtyfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCnNraW1yOjpza2ltKHBtKQpgYGAKCiMjIyMKCk5vdGljZSBob3cgdGhlcmUgaXMgYSBjb2x1bW4gY2FsbGVkIGBuX21pc3NpbmdgIGFib3V0IHRoZSBudW1iZXIgb2YgdmFsdWVzIHRoYXQgYXJlIG1pc3NpbmcuIAoKVGhpcyBpcyBhbHNvIGluZGljYXRlZCBieSB0aGUgYGNvbXBsZXRlX3JhdGVgIHZhcmlhYmxlIChvciBtaXNzaW5nL251bWJlciBvZiBvYnNlcnZhdGlvbnMpLiAKCkluIG91ciBkYXRhIHNldCwgaXQgbG9va3MgbGlrZSBvdXIgZGF0YSBkbyBub3QgY29udGFpbiBhbnkgbWlzc2luZyBkYXRhLiAKCkFsc28gbm90aWNlIGhvdyB0aGUgZnVuY3Rpb24gcHJvdmlkZXMgc2VwYXJhdGUgdGFibGVzIG9mIHN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZWFjaCBkYXRhIHR5cGU6IGNoYXJhY3RlciwgZmFjdG9yIGFuZCBudW1lcmljLiAKCk5leHQsIHRoZSBgbl91bnFpdWVgIGNvbHVtbiBzaG93cyB1cyB0aGUgbnVtYmVyIG9mIHVuaXF1ZSB2YWx1ZXMgZm9yIGVhY2ggb2Ygb3VyIGNvbHVtbnMuIApXZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIDQ5IHN0YXRlcyByZXByZXNlbnRlZCBpbiB0aGUgZGF0YS4KCldlIGNhbiBzZWUgdGhhdCBmb3IgbWFueSB2YXJpYWJsZXMgdGhlcmUgYXJlIG1hbnkgbG93IHZhbHVlcyBhcyB0aGUgZGlzdHJpYnV0aW9uIHNob3dzIHR3byBwZWFrcywgb25lIG5lYXIgemVybyBhbmQgYW5vdGhlciB3aXRoIGEgaGlnaGVyIHZhbHVlLiAKClRoaXMgaXMgdHJ1ZSBmb3IgdGhlIGBpbXBgIHZhcmlhYmxlcyAobWVhc3VyZXMgb2YgZGV2ZWxvcG1lbnQpLCB0aGUgYG5laWAgdmFyaWFibGVzIChtZWFzdXJlcyBvZiBlbWlzc2lvbiBzb3VyY2VzKSBhbmQgdGhlIHJvYWQgZGVuc2l0eSB2YXJpYWJsZXMuIAoKV2UgY2FuIGFsc28gc2VlIHRoYXQgdGhlIHJhbmdlIG9mIHNvbWUgb2YgdGhlIHZhcmlhYmxlcyBpcyB2ZXJ5IGxhcmdlLCBpbiBwYXJ0aWN1bGFyIHRoZSBhcmVhIGFuZCBwb3B1bGF0aW9uIHJlbGF0ZWQgdmFyaWFibGVzLgoKCkxldCdzIHRha2UgYSBsb29rIHRvIHNlZSB3aGljaCBzdGF0ZXMgYXJlIGluY2x1ZGVkIHVzaW5nIHRoZSBgZGlzdGluY3QoKWAgZnVuY3Rpb24gb2YgdGhlIGBkcGx5cmAgcGFja2FnZToKCmBgYHtyLCBldmFsID0gRkFMU0V9IApwbSAlPiUgCiAgZHBseXI6OmRpc3RpbmN0KHN0YXRlKSAKYGBgCgoKU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dDoKCiMjIyMgey5zY3JvbGxhYmxlIH0KYGBge3IsIGVjaG8gPSBGQUxTRX0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpwbSAlPiUgCiAgZGlzdGluY3Qoc3RhdGUpICU+JQojIHRoaXMgYWxsb3dzIHVzIHRvIHNob3cgdGhlIGZ1bGwgb3V0cHV0IGluIHRoZSByZW5kZXJlZCBybWFya2Rvd24KIHByaW50KG4gPSAxZTMpCmBgYAojIyMjCgpJdCBsb29rcyBsaWtlICJEaXN0cmljdCBvZiBDb2x1bWJpYSIgaXMgYmVpbmcgaW5jbHVkZWQgYXMgYSBzdGF0ZS4gCldlIGNhbiBzZWUgdGhhdCBBbGFza2EgYW5kIEhhd2FpaSBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSBkYXRhLgoKTGV0J3MgYWxzbyB0YWtlIGEgbG9vayB0byBzZWUgaG93IG1hbnkgbW9uaXRvcnMgdGhlcmUgYXJlIGluIGEgZmV3IGNpdGllcy4gV2UgY2FuIHVzZSB0aGUgYGZpbHRlcigpYCBmdW5jdGlvbiBvZiB0aGUgYGRwbHlyYCBwYWNrYWdlIHRvIGRvIHNvLiBGb3IgZXhhbXBsZSwgbGV0J3MgbG9vayBhdCBBbGJ1cXVlcnF1ZSwgTmV3IE1leGljby4gCgpgYGB7cn0KcG0gJT4lIGRwbHlyOjpmaWx0ZXIoY2l0eSA9PSAiQWxidXF1ZXJxdWUiKQoKYGBgCgpXZSBjYW4gc2VlIHRoYXQgdGhlcmUgd2VyZSBvbmx5IHR3byBtb25pdG9ycyBpbiB0aGUgY2l0eSBvZiBBbGJ1cXVlcnF1ZSBpbiAyMDA2LiBMZXQncyBjb21wYXJlIHRoaXMgd2l0aCBCYWx0aW1vcmUuCgpgYGB7cn0KcG0gJT4lIGRwbHlyOjpmaWx0ZXIoY2l0eSA9PSAiQmFsdGltb3JlIikKCmBgYAoKVGhlcmUgd2VyZSBpbiBjb250cmFzdCBmaXZlIG1vbml0b3JzIGZvciB0aGUgY2l0eSBvZiBCYWx0aW1vcmUsIGRlc3BpdGUgdGhlIGZhY3QgdGhhdCBpZiB3ZSB0YWtlIGEgbG9vayBhdCB0aGUgbGFuZCBhcmVhIGFuZCBwb3B1bGF0aW9uIG9mIHRoZSBjb3VudGllcyBmb3IgQmxhdGltb3JlIENpdHkgYW5kIEFsYnVxdWVycXVlLCB3ZSBjYW4gc2VlIHRoYXQgdGhleSBoYWQgdmVyeSBzaW1pbGFyIGxhbmQgYXJlYSBhbmQgcG9wdWxhdGlvbnMuCgpgYGB7cn0KcG0gJT4lIAogIGRwbHlyOjpmaWx0ZXIoY2l0eSA9PSAiQmFsdGltb3JlIikgJT4lIAogIHNlbGVjdChjb3VudHlfYXJlYTpjb3VudHlfcG9wKQpwbSAlPiUgCiAgZHBseXI6OmZpbHRlcihjaXR5ID09ICJBbGJ1cXVlcnF1ZSIpICU+JQogIHNlbGVjdChjb3VudHlfYXJlYTpjb3VudHlfcG9wKQoKYGBgCgpJbiBmYWN0LCB0aGUgY291bnR5IGNvbnRhaW5pbmcgQWxidWVycXVlIGhhZCBhIGxhcmdlciBwb3B1bGF0aW9uLiBUaHVzIHRoZSBtZWFzdXJlbWVudHMgZm9yIEFsYnVxdWVycXVlIHdlcmUgbm90IGFzIHRob3JvdWdoIGFzIHRoZXkgd2VyZSBmb3IgQmFsdGltb3JlLgoKVGhpcyBtYXkgYmUgZHVlIHRvIHRoZSBmYWN0IHRoYXQgdGhlIG1vbml0b3IgdmFsdWVzIHdlcmUgbG93ZXIgaW4gQWxidXF1ZXJxdWUuIEl0IGlzIGludGVyZXN0aW5nIHRvIG5vdGUgaGVyZSB0aGF0IHRoZSBDTUFRIHZhbHVlcyBhcmUgcXVpdGUgc2ltaWxhciBmb3IgYm90aCBjaXRpZXMuCgoKIyMgKipFdmFsdWF0ZSBjb3JyZWxhdGlvbioqCioqKgoKSW4gcHJlZGljdGlvbiBhbmFseXNlcywgaXQgaXMgYWxzbyB1c2VmdWwgdG8gZXZhbHVhdGUgaWYgYW55IG9mIHRoZSB2YXJpYWJsZXMgYXJlIGNvcnJlbGF0ZWQuIFdoeSBzaG91bGQgd2UgY2FyZSBhYm91dCB0aGlzPwoKSWYgd2UgYXJlIHVzaW5nIGEgbGluZWFyIHJlZ3Jlc3Npb24gdG8gbW9kZWwgb3VyIGRhdGEgdGhlbiB3ZSBtaWdodCBydW4gaW50byBhIHByb2JsZW0gY2FsbGVkIG11bHRpY29saW5lYXJpdHkgd2hpY2ggY2FuIGxlYWQgdXMgdG8gbWlzaW50ZXJwcmV0IHdoYXQgaXMgcmVhbGx5IHByZWRpY3RpdmUgb2Ygb3VyIG91dGNvbWUgdmFyaWFibGUuIFRoaXMgcGhlbm9tZW5vbiBvY2N1cnMgd2hlbiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyBhY3R1YWxseSBwcmVkaWN0IG9uZSBhbm90aGVyLiBTZWUgW3RoaXMgY2FzZSBzdHVkeV0oaHR0cHM6Ly9vcGVuY2FzZXN0dWRpZXMuZ2l0aHViLmlvL29jcy1icC1SVEMtYW5hbHlzaXMvKSBmb3IgYSBkZWVwZXIgZXhwbGFuYXRpb24gYWJvdXQgdGhpcy4gCgpBbm90aGVyIHJlYXNvbiB3ZSBzaG91bGQgbG9vayBvdXQgZm9yIGNvcnJlbGF0aW9uIGlzIHRoYXQgd2UgZG9uJ3Qgd2FudCB0byBpbmNsdWRlIHJlZHVuZGFudCB2YXJpYWJsZXMuIFRoaXMgY2FuIGFkZCB1bm5lY2Vzc2FyeSBub2lzZSB0byBvdXIgYWxnb3JpdGhtIGNhdXNpbmcgYSByZWR1Y3Rpb24gaW4gcHJlZGljdGlvbiBhY2N1cmFjeSBhbmQgaXQgY2FuIGNhdXNlIG91ciBhbGdvcml0aG0gdG8gYmUgdW5uZWNlc3NhcmlseSBzbG93ZXIuIEZpbmFsbHksIGl0IGNhbiBhbHNvIG1ha2UgaXQgZGlmZmljdWx0IHRvIGludGVycHJldCB3aGF0IHZhcmlhYmxlcyBhcmUgYWN0dWFsbHkgcHJlZGljdGl2ZS4KCkludHVpdGl2ZWx5IHdlIGNhbiBleHBlY3Qgc29tZSBvZiBvdXIgdmFyaWFibGVzIHRvIGJlIGNvcnJlbGF0ZWQuCgpMZXQncyBmaXJzdCB0YWtlIGEgbG9vayBhdCBhbGwgb2Ygb3VyIG51bWVyaWMgdmFyaWFibGVzIHdpdGggdGhlYGNvcnJwbG90YCBwYWNrYWdlOgpUaGUgYGNvcnJwbG90YCBwYWNrYWdlIGlzIGFub3RoZXIgb3B0aW9uIHRvIGxvb2sgYXQgY29ycmVsYXRpb24gYW1vbmcgcG9zc2libGUgcHJlZGljdG9ycywgYW5kIHBhcnRpY3VsYXJseSB1c2VmdWwgaWYgd2UgaGF2ZSBtYW55IHByZWRpY3RvcnMuIAoKRmlyc3QsIHdlIGNhbGN1bGF0ZSB0aGUgUGVhcnNvbiBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgYmV0d2VlbiBhbGwgZmVhdHVyZXMgcGFpcndpc2UgdXNpbmcgdGhlIGBjb3IoKWAgZnVuY3Rpb24gb2YgdGhlIGBzdGF0c2AgcGFja2FnZSAod2hpY2ggaXMgbG9hZGVkIGF1dG9tYXRpY2FsbHkpLiBUaGVuIHdlIHVzZSB0aGUgYGNvcnJwbG90Ojpjb3JycGxvdCgpYCBmdW5jdGlvbi4gCgpgYGB7cn0KUE1fY29yIDwtIGNvcihwbSAlPiUgZHBseXI6OnNlbGVjdF9pZihpcy5udW1lcmljKSkKY29ycnBsb3Q6OmNvcnJwbG90KFBNX2NvciwgdGwuY2V4ID0gMC41KQpgYGAKVGhlIGB0bC5jZXggPSAwLjVgIGFyZ3VtZW50IGNvbnRyb2xzIHRoZSBzaXplIG9mIHRoZSB0ZXh0IGxhYmVsLiAKCldlIGNhbiBhbHNvIHBsb3QgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBQZWFyc29uIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyB1c2luZyB0aGUgYGFicygpYCBmdW5jdGlvbiBmcm9tIGJhc2UgUiBhbmQgY2hhbmdlIHRoZSBvcmRlciBvZiB0aGUgY29sdW1ucy4gIApgYGB7cn0KY29ycnBsb3QoYWJzKFBNX2NvciksIG9yZGVyID0gImhjbHVzdCIsIHRsLmNleCA9IDAuNSwgY2wubGltID0gYygwLCAxKSkKCmBgYAoKVGhlcmUgYXJlIHNldmVyYWwgb3B0aW9ucyBmb3Igb3JkZXJpbmcgdGhlIHZhcmlhYmxlcy4gU2VlIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvY29ycnBsb3QvdmlnbmV0dGVzL2NvcnJwbG90LWludHJvLmh0bWwpIGZvciBtb3JlIG9wdGlvbnMuIEhlcmUgd2Ugd2lsbCB1c2UgdGhlICJoY2x1c3QiIG9wdGlvbiBmb3Igb3JkZXJpbmcgYnkgW2hpZXJhcmNoaWNhbCBjbHVzdGVyaW5nXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9IaWVyYXJjaGljYWxfY2x1c3RlcmluZykgLSB3aGljaCB3aWxsIG9yZGVyIHRoZSB2YXJpYWJsZXMgYnkgaG93IHNpbWlsYXIgdGhleSBhcmUgdG8gb25lIGFub3RoZXIuCgpUaGUgYGNsLmxpbSA9IGMoMCwgMSlgIGFyZ3VtZW50IGxpbWl0cyB0aGUgY29sb3IgbGFiZWwgdG8gYmUgYmV0d2VlbiAwIGFuZCAxLiAKCgpXZSBjYW4gc2VlIHRoYXQgdGhlIGRldmVsb3BtZW50IHZhcmlhYmxlcyAoYGltcGApIHZhcmlhYmxlcyBhcmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIgYXMgd2UgbWlnaHQgZXhwZWN0LiAKV2UgYWxzbyBzZWUgdGhhdCB0aGUgcm9hZCBkZW5zaXR5IHZhcmlhYmxlcyBzZWVtIHRvIGJlIGNvcnJlbGF0ZWQgd2l0aCBlYWNoIG90aGVyLCBhbmQgdGhlIGVtaXNzaW9uIHZhcmlhYmxlcyBzZWVtIHRvIGJlIGNvcnJlbGF0ZWQgd2l0aCBlYWNoIG90aGVyLiAKCgpBbHNvIG5vdGljZSB0aGF0IG5vbmUgb2YgdGhlIHByZWRpY3RvcnMgYXJlIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggb3VyIG91dGNvbWUgdmFyaWFibGUgKGB2YWx1ZWApLgoKV2UgY2FuIHRha2UgYWxzbyB0YWtlIGEgY2xvc2VyIGxvb2sgIHVzaW5nIHRoZSBgZ2djb3JyKClgIGZ1bmN0aW9uIGFuZCB0aGUgYGdncGFpcnMoKWAgZnVuY3Rpb24gb2YgdGhlIGBHR2FsbHlgIHBhY2thZ2UuIAoKVG8gc2VsZWN0IG91ciB2YXJpYWJsZXMgb2YgaW50ZXJlc3Qgd2UgY2FuIHVzZSB0aGUgYHNlbGVjdCgpYCBmdW5jdGlvbiB3aXRoIHRoZSBgY29udGFpbnMoKWAgZnVuY3Rpb24gb2YgdGhlIGB0aWR5cmAgcGFja2FnZS4gCgpGaXJzdCBsZXQncyBsb29rIGF0IHRoZSBgaW1wYC9kZXZlbG9wbWVudCB2YXJpYWJsZXMuIApXZSBjYW4gY2hhbmdlIHRoZSBkZWZhdWx0IGNvbG9yIHBhbGV0dGUgKGBwYWxldHRlID0gIlJkQnUiYCkgYW5kIGFkZCBvbiAKY29ycmVsYXRpb24gY29lZmZpY2llbnRzIHRvIHRoZSBwbG90IChgbGFiZWwgPSBUUlVFYCkuCgpgYGB7ciwgb3V0LndpZHRoID0gIjQwMHB4In0Kc2VsZWN0KHBtLCBjb250YWlucygiaW1wIikpICU+JQogIGdnY29ycihwYWxldHRlID0gIlJkQnUiLCBsYWJlbCA9IFRSVUUpCgpzZWxlY3QocG0sIGNvbnRhaW5zKCJpbXAiKSkgJT4lCiAgZ2dwYWlycygpCmBgYAoKCgpJbmRlZWQsIHdlIGNhbiBzZWUgdGhhdCBgaW1wX2ExMDAwYCBhbmQgYGltcF9hNTAwYCBhcmUgaGlnaGx5IGNvcnJlbGF0ZWQsIGFzIHdlbGwgYXMgYGltcF9hMTAwMDBgLCBgaW1wX2ExNTAwMGAuCgpOZXh0LCBsZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgcm9hZCBkZW5zaXR5IGRhdGE6CgpgYGB7ciwgZmlnLndlaWdodD0xMn0Kc2VsZWN0KHBtLCBjb250YWlucygicHJpIikpICU+JQogIGdnY29ycihwYWxldHRlID0gIlJkQnUiLCBoanVzdCA9IC44NSwgc2l6ZSA9IDMsCiAgICAgICBsYXlvdXQuZXhwPTIsIGxhYmVsID0gVFJVRSkKYGBgCgpXZSBjYW4gc2VlIHRoYXQgbWFueSBvZiB0aGUgcm9hZCBkZW5zaXR5IHZhcmlhYmxlcyBhcmUgaGlnaGx5IGNvcnJlbGF0ZWQgd2l0aCBvbmUgYW5vdGhlciwgd2hpbGUgb3RoZXJzIGFyZSBsZXNzIHNvLgoKRmluYWxseSBsZXQncyBsb29rIGF0IHRoZSBlbWlzc2lvbiB2YXJpYWJsZXMuCgpgYGB7cn0Kc2VsZWN0KHBtLCBjb250YWlucygibmVpIikpICU+JQogIGdnY29ycihwYWxldHRlID0gIlJkQnUiLCBoanVzdCA9IC44NSwgc2l6ZSA9IDMsCiAgICAgICBsYXlvdXQuZXhwPTIsIGxhYmVsID0gVFJVRSkKCnNlbGVjdChwbSwgY29udGFpbnMoIm5laSIpKSAlPiUKICBnZ3BhaXJzKCkKYGBgCgpXZSB3b3VsZCBhbHNvIGV4cGVjdCB0aGUgcG9wdWxhdGlvbiBkZW5zaXR5IGRhdGEgbWlnaHQgY29ycmVsYXRlIHdpdGggc29tZSBvZiB0aGVzZSB2YXJpYWJsZXMuIApMZXQncyB0YWtlIGEgbG9vay4KCmBgYHtyfQpwbSAlPiUKc2VsZWN0KGxvZ19uZWlfMjAwOF9wbTI1X3N1bV8xMDAwMCwgcG9wZGVuc19jb3VudHksIAogICAgICAgbG9nX3ByaV9sZW5ndGhfMTAwMDAsIGltcF9hMTAwMDApICU+JQogIGdnY29ycihwYWxldHRlID0gIlJkQnUiLCAgaGp1c3QgPSAuODUsIHNpemUgPSAzLAogICAgICAgbGF5b3V0LmV4cD0yLCBsYWJlbCA9IFRSVUUpCgpwbSAlPiUKc2VsZWN0KGxvZ19uZWlfMjAwOF9wbTI1X3N1bV8xMDAwMCwgcG9wZGVuc19jb3VudHksIAogICAgICAgbG9nX3ByaV9sZW5ndGhfMTAwMDAsIGltcF9hMTAwMDAsIGNvdW50eV9wb3ApICU+JQogIGdncGFpcnMoKQpgYGAKCgpJbnRlcmVzdGluZywgc28gdGhlc2UgdmFyaWFibGVzIGRvbid0IGFwcGVhciB0byBiZSBoaWdobHkgY29ycmVsYXRlZCwgdGhlcmVmb3JlIHdlIG1pZ2h0IG5lZWQgdmFyaWFibGVzIGZyb20gZWFjaCBvZiB0aGUgY2F0ZWdvcmllcyB0byBwcmVkaWN0IG91ciBtb25pdG9yIFBNfjIuNX4gcG9sbHV0aW9uIHZhbHVlcy4KCkJlY2F1c2Ugc29tZSB2YXJpYWJsZXMgaW4gb3VyIGRhdGEgaGF2ZSBleHRyZW1lIHZhbHVlcywgaXQgbWlnaHQgYmUgZ29vZCB0byB0YWtlIGEgbG9nIHRyYW5zZm9ybWF0aW9uLiBUaGlzIGNhbiBhZmZlY3Qgb3VyIGVzdGltYXRlcyBvZiBjb3JyZWxhdGlvbi4gCmBgYHtyfQpwbSAlPiUKICBtdXRhdGUobG9nX3BvcGRlbnNfY291bnR5PSBsb2cocG9wZGVuc19jb3VudHkpKSAlPiUKc2VsZWN0KGxvZ19uZWlfMjAwOF9wbTI1X3N1bV8xMDAwMCwgbG9nX3BvcGRlbnNfY291bnR5LCAKICAgICAgIGxvZ19wcmlfbGVuZ3RoXzEwMDAwLCBpbXBfYTEwMDAwKSAlPiUKICBnZ2NvcnIocGFsZXR0ZSA9ICJSZEJ1IiwgIGhqdXN0ID0gLjg1LCBzaXplID0gMywKICAgICAgIGxheW91dC5leHA9MiwgbGFiZWwgPSBUUlVFKQoKcG0gJT4lCiAgbXV0YXRlKGxvZ19wb3BkZW5zX2NvdW50eT0gbG9nKHBvcGRlbnNfY291bnR5KSkgJT4lCiAgbXV0YXRlKGxvZ19wb3BfY291bnR5ID0gbG9nKGNvdW50eV9wb3ApKSAlPiUKc2VsZWN0KGxvZ19uZWlfMjAwOF9wbTI1X3N1bV8xMDAwMCwgbG9nX3BvcGRlbnNfY291bnR5LCAKICAgICAgIGxvZ19wcmlfbGVuZ3RoXzEwMDAwLCBpbXBfYTEwMDAwLCBsb2dfcG9wX2NvdW50eSkgJT4lCiAgZ2dwYWlycygpCmBgYAoKSW5kZWVkIHRoaXMgaW5jcmVhc2VkIHRoZSBjb3JyZWxhdGlvbiwgYnV0IHZhcmlhYmxlcyBmcm9tIGVhY2ggb2YgdGhlc2UgY2F0ZWdvcmllcyBtYXkgc3RpbGwgcHJvdmUgdG8gYmUgdXNlZnVsIGZvciBwcmVkaWN0aW9uLgoKTm93IHRoYXQgd2UgaGF2ZSBhIHNlbnNlIG9mIHdoYXQgb3VyIGRhdGEgYXJlLCB3ZSBjYW4gZ2V0IHN0YXJ0ZWQgd2l0aCBidWlsZGluZyBhIG1hY2hpbmUgbGVhcm5pbmcgbW9kZWwgdG8gcHJlZGljdCBhaXIgcG9sbHV0aW9uLiAKCiMgKipXaGF0IGlzIG1hY2hpbmUgbGVhcm5pbmc/KiogIHsjd2hhdGlzbWx9CioqKgoKWW91IG1heSBoYXZlIGxlYXJuZWQgYWJvdXQgdGhlIGNlbnRyYWwgZG9nbWEgb2Ygc3RhdGlzdGljcyB0aGF0IHlvdSBzYW1wbGUgZnJvbSBhIHBvcHVsYXRpb24uCgohW10oaW1nL2NkaTEucG5nKQoKVGhlbiB5b3UgdXNlIHRoZSBzYW1wbGUgdG8gdHJ5IHRvIGd1ZXNzIHdoYXQgaXMgaGFwcGVuaW5nIGluIHRoZSBwb3B1bGF0aW9uLgoKIVtdKGltZy9jZGkyLnBuZykKCkZvciBwcmVkaWN0aW9uIHdlIGhhdmUgYSBzaW1pbGFyIHNhbXBsaW5nIHByb2JsZW0KCiFbXShpbWcvY2RwMS5wbmcpCgpCdXQgbm93IHdlIGFyZSB0cnlpbmcgdG8gYnVpbGQgYSBydWxlIHRoYXQgY2FuIGJlIHVzZWQgdG8gcHJlZGljdCBhIHNpbmdsZSBvYnNlcnZhdGlvbidzIHZhbHVlIG9mIHNvbWUgY2hhcmFjdGVyaXN0aWMgdXNpbmcgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBvdGhlciBvYnNlcnZhdGlvbnMuIAoKIVtdKGltZy9jZHAyLnBuZykKCkxldCdzIG1ha2UgdGhpcyBtb3JlIGNvbmNyZXRlLgoKSWYgeW91IHJlY2FsbCBmcm9tIHRoZSBbV2hhdCBhcmUgdGhlIGRhdGE/XSgjd2hhdGFyZXRoZWRhdGEpIHNlY3Rpb24gYWJvdmUsIHdoZW4gd2UgYXJlIHVzaW5nIG1hY2hpbmUgbGVhcm5pbmcgZm9yIHByZWRpY3Rpb24sIG91ciBkYXRhIGNvbnNpc3RzIG9mOiAKCjEuIEFuICoqY29udGludW91cyoqIG91dGNvbWUgdmFyaWFibGUgdGhhdCB3ZSB3YW50IHRvIHByZWRpY3QgCjIuIEEgc2V0IG9mIGZlYXR1cmUocykgKG9yIHByZWRpY3RvciB2YXJpYWJsZXMpIHRoYXQgd2UgdXNlIHRvIHByZWRpY3QgdGhlIG91dGNvbWUgdmFyaWFibGUKCldlIHdpbGwgdXNlICRZJCB0byBkZW5vdGUgdGhlIG91dGNvbWUgdmFyaWFibGUgYW5kICRYID0gKFhfMSwgXGRvdHMsIFhfcCkkIHRvIGRlbm90ZSAkcCQgZGlmZmVyZW50IGZlYXR1cmVzIChvciBwcmVkaWN0b3IgdmFyaWFibGVzKS4gCkJlY2F1c2Ugb3VyIG91dGNvbWUgdmFyaWFibGUgaXMgKipjb250aW51b3VzKiogKGFzIG9wcG9zZWQgdG8gY2F0ZWdvcmljYWwpLCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBhIHBhcnRpY3VsYXIgdHlwZSBvZiBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobS4gCgpPdXIgZ29hbCBpcyB0byBidWlsZCBhIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtIHRoYXQgdXNlcyB0aGUgZmVhdHVyZXMgJFgkIGFzIGlucHV0IGFuZCBwcmVkaWN0cyBhbiBvdXRjb21lIHZhcmlhYmxlIChvciBhaXIgcG9sbHV0aW9uIGxldmVscykgaW4gdGhlIHNpdHVhdGlvbiB3aGVyZSB3ZSBkbyBub3Qga25vdyB0aGUgb3V0Y29tZSB2YXJpYWJsZS4gCgpUaGUgd2F5IHdlIGRvIHRoaXMgaXMgdG8gdXNlIGRhdGEgd2hlcmUgd2UgaGF2ZSBib3RoIHRoZSBmZWF0dXJlcyAkKFhfMT14XzEsIFxkb3RzIFhfcD14X3ApJCBhbmQgdGhlIGFjdHVhbCBvdXRjb21lICRZJCBkYXRhIHRvIF90cmFpbl8gYSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobSB0byBwcmVkaWN0IHRoZSBvdXRjb21lLCB3aGljaCB3ZSBjYWxsICRcaGF0e1l9JC4gIAoKV2hlbiB3ZSBzYXkgdHJhaW4gYSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobSB3ZSBtZWFuIHRoYXQgd2UgZXN0aW1hdGUgYSBmdW5jdGlvbiAkZiQgdGhhdCB1c2VzIHRoZSBwcmVkaWN0b3IgdmFyaWFibGVzICRYJCBhcyBpbnB1dCBvciAkXGhhdHtZfSA9IGYoWCkkLiAKCiMjICoqTUwgYXMgYW4gb3B0aW1pemF0aW9uIHByb2JsZW0qKgoKSWYgd2UgYXJlIGRvaW5nIGEgZ29vZCBqb2IsIHRoZW4gb3VyIHByZWRpY3RlZCBvdXRjb21lICRcaGF0e1l9JCBzaG91bGQgY2xvc2VseSBtYXRjaCBvdXIgYWN0dWFsIG91dGNvbWUgJFkkIHRoYXQgd2Ugb2JzZXJ2ZWQuIAoKSW4gdGhpcyB3YXksIHdlIGNhbiB0aGluayBvZiBtYWNoaW5lIGxlYXJuaW5nIChNTCkgYXMgYW4gb3B0aW1pemF0aW9uIHByb2JsZW0gdGhhdCB0cmllcyB0byBtaW5pbWl6ZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiAkXGhhdHtZfSA9IGYoWCkkIGFuZCAkWSQuIAoKJCRkKFkgLSBmKFgpKSQkClRoZSBjaG9pY2Ugb2YgZGlzdGFuY2UgbWV0cmljICRkKFxjZG90KSQgY2FuIGJlIHRoZSBtZWFuIG9mIHRoZSBhYnNvbHV0ZSBvciBzcXVhcmVkIGRpZmZlcmVuY2Ugb3Igc29tZXRoaW5nIG1vcmUgY29tcGxpY2F0ZWQuIAoKTXVjaCBvZiB0aGUgZmllbGRzIG9mIHN0YXRpc3RpY3MgYW5kIGNvbXB1dGVyIHNjaWVuY2UgYXJlIGZvY3VzZWQgb24gZGVmaW5pbmcgJGYkIGFuZCAkZCQuCgojIyAqKlRoZSBwYXJ0cyBvZiBhbiBNTCBwcm9ibGVtKioKClRvIHNldCB1cCBhIG1hY2hpbmUgbGVhcm5pbmcgKE1MKSBwcm9ibGVtLCB3ZSBuZWVkIGEgZmV3IGNvbXBvbmVudHMuClRvIHNvbHZlIGEgKHN0YW5kYXJkKSBtYWNoaW5lIGxlYXJuaW5nIHByb2JsZW0geW91IG5lZWQ6IAoKMS4gQSBkYXRhIHNldCB0byB0cmFpbiBmcm9tLiAKMi4gQW4gYWxnb3JpdGhtIG9yIHNldCBvZiBhbGdvcml0aG1zIHlvdSBjYW4gdXNlIHRvIHRyeSB2YWx1ZXMgb2YgJGYkCjMuIEEgZGlzdGFuY2UgbWV0cmljICRkJCBmb3IgbWVhc3VyaW5nIGhvdyBjbG9zZSAkWSQgaXMgdG8gJFxoYXR7WX0kCjQuIEEgZGVmaW5pdGlvbiBvZiB3aGF0IGEgImdvb2QiIGRpc3RhbmNlIGlzCgpXaGlsZSBlYWNoIG9mIHRoZXNlIGNvbXBvbmVudHMgaXMgYSBfdGVjaG5pY2FsXyBwcm9ibGVtLCB0aGVyZSBoYXMgYmVlbiBhIHRvbiBvZiB3b3JrIGFkZHJlc3NpbmcgdGhvc2UgdGVjaG5pY2FsIGRldGFpbHMuIFRoZSBtb3N0IHByZXNzaW5nIG9wZW4gaXNzdWUgaW4gbWFjaGluZSBsZWFybmluZyBpcyByZWFsaXppbmcgdGhhdCB0aG91Z2ggdGhlc2UgYXJlIF90ZWNobmljYWxfIHN0ZXBzIHRoZXkgYXJlIG5vdCBfb2JqZWN0aXZlXyBzdGVwcy4gSW4gb3RoZXIgd29yZHMsIGhvdyB5b3UgY2hvb3NlIHRoZSBkYXRhLCBhbGdvcml0aG0sIG1ldHJpYywgYW5kIGRlZmluaXRpb24gb2YgImdvb2QiIHNheXMgd2hhdCB5b3UgdmFsdWUgYW5kIGNhbiBkcmFtYXRpY2FsbHkgY2hhbmdlIHRoZSByZXN1bHRzLiBBIGNvdXBsZSBvZiBjYXNlcyB3aGVyZSB0aGlzIHdhcyBhIGJpZyBkZWFsIGFyZTogCgoxLiBbTWFjaGluZSBsZWFybmluZyBmb3IgcmVjaWRpdmlzbV0oaHR0cHM6Ly93d3cucHJvcHVibGljYS5vcmcvYXJ0aWNsZS9tYWNoaW5lLWJpYXMtcmlzay1hc3Nlc3NtZW50cy1pbi1jcmltaW5hbC1zZW50ZW5jaW5nKSAtIHBlb3BsZSBidWlsdCBNTCBtb2RlbHMgdG8gcHJlZGljdCB3aG8gd291bGQgcmUtY29tbWl0IGEgY3JpbWUuIEJ1dCB0aGVzZSBwcmVkaWN0aW9ucyB3ZXJlIGJhc2VkIG9uIGhpc3RvcmljYWxseSBiaWFzZWQgZGF0YSB3aGljaCBsZWQgdG8gYmlhc2VkIHByZWRpY3Rpb25zIGFib3V0IHdobyB3b3VsZCBjb21taXQgbmV3IGNyaW1lcy4gCjIuIFtEZWNpZGluZyBob3cgc2VsZiBkcml2aW5nIGNhcnMgc2hvdWxkIGFjdF0oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9kNDE1ODYtMDE4LTA3MTM1LTApIC0gc2VsZiBkcml2aW5nIGNhcnMgd2lsbCBoYXZlIHRvIG1ha2UgZGVjaXNpb25zIGFib3V0IGhvdyB0byBkcml2ZSwgd2hvIHRoZXkgbWlnaHQgaW5qdXJlLCBhbmQgaG93IHRvIGF2b2lkIGFjY2lkZW50cy4gRGVwZW5kaW5nIG9uIG91ciBjaG9pY2VzIGZvciAkZiQgYW5kICRkJCB0aGVzZSBtaWdodCBsZWFkIHRvIHdpbGRseSBkaWZmZXJlbnQga2luZHMgb2Ygc2VsZiBkcml2aW5nIGNhcnMuIFRyeSBvdXQgdGhlIFttb3JhbG1hY2hpbmVdKGh0dHA6Ly9tb3JhbG1hY2hpbmUubWl0LmVkdS8pIHRvIHNlZSBob3cgdGhpcyBsb29rcyBpbiBwcmFjdGljZS4gCgpOb3cgdGhhdCB3ZSBrbm93IGEgYml0IG1vcmUgYWJvdXQgbWFjaGluZSBsZWFybmluZywgbGV0J3MgYnVpbGQgYSBtb2RlbCB0byBwcmVkaWN0IGFpciBwb2xsdXRpb24gbGV2ZWxzIHVzaW5nIHRoZSBgdGlkeW1vZGVsc2AgZnJhbWV3b3JrLiAKCiMgKipNYWNoaW5lIGxlYXJuaW5nIHdpdGggYHRpZHltb2RlbHNgKioKKioqClRoZSBnb2FsIGlzIHRvIGJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBhbGdvcml0aG0gdXNlcyB0aGUgZmVhdHVyZXMgYXMgaW5wdXQgYW5kIHByZWRpY3RzIGEgb3V0Y29tZSB2YXJpYWJsZSAob3IgYWlyIHBvbGx1dGlvbiBsZXZlbHMpIGluIHRoZSBzaXR1YXRpb24gd2hlcmUgd2UgZG8gbm90IGtub3cgdGhlIG91dGNvbWUgdmFyaWFibGUuIAoKVGhlIHdheSB3ZSBkbyB0aGlzIGlzIHRvIHVzZSBkYXRhIHdoZXJlIHdlIGhhdmUgYm90aCB0aGUgaW5wdXQgYW5kIG91dHB1dCBkYXRhIHRvIF90cmFpbl8gYSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobS4gCgpUbyB0cmFpbiBhIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtLCB3ZSB3aWxsIHVzZSB0aGUgYHRpZHltb2RlbHNgIHBhY2thZ2UgZWNvc3lzdGVtLiAKCiMjICoqT3ZlcnZpZXcqKgoqKioKCiMjIyAqKlRoZSBgdGlkeW1vZGVsc2AgZWNvc3lzdGVtKioKKioqCgpUbyBwZXJmb3JtIG91ciBhbmFseXNpcyB3ZSB3aWxsIGJlIHVzaW5nIHRoZSBgdGlkeW1vZGVsc2Agc3VpdGUgb2YgcGFja2FnZXMuIApZb3UgbWF5IGJlIGZhbWlsaWFyIHdpdGggdGhlIG9sZGVyIHBhY2thZ2VzIGBjYXJldGAgb3IgYG1scmAgd2hpY2ggYXJlIGFsc28gZm9yIG1hY2hpbmUgbGVhcm5pbmcgYW5kIG1vZGVsaW5nIGJ1dCBhcmUgbm90IGEgcGFydCBvZiB0aGUgYHRpZHl2ZXJzZWAuIApbTWF4IEt1aG5dKGh0dHBzOi8vcmVzb3VyY2VzLnJzdHVkaW8uY29tL2F1dGhvcnMvbWF4LWt1aG4pe3RhcmdldD0iX2JsYW5rIn0gZGVzY3JpYmVzIGB0aWR5bW9kZWxzYCBsaWtlIHRoaXM6Cgo+ICJPdGhlciBwYWNrYWdlcywgc3VjaCBhcyBjYXJldCBhbmQgbWxyLCBoZWxwIHRvIHNvbHZlIHRoZSBSIG1vZGVsIEFQSSBpc3N1ZS4gVGhlc2UgcGFja2FnZXMgZG8gYSBsb3Qgb2Ygb3RoZXIgdGhpbmdzIHRvbzogcHJlLXByb2Nlc3NpbmcsIG1vZGVsIHR1bmluZywgcmVzYW1wbGluZywgZmVhdHVyZSBzZWxlY3Rpb24sIGVuc2VtYmxpbmcsIGFuZCBzbyBvbi4gSW4gdGhlIHRpZHl2ZXJzZSwgd2Ugc3RyaXZlIHRvIG1ha2Ugb3VyIHBhY2thZ2VzIG1vZHVsYXIgYW5kIHBhcnNuaXAgaXMgZGVzaWduZWQgb25seSB0byBzb2x2ZSB0aGUgaW50ZXJmYWNlIGlzc3VlLiBJdCBpcyBub3QgZGVzaWduZWQgdG8gYmUgYSBkcm9wLWluIHJlcGxhY2VtZW50IGZvciBjYXJldC4KVGhlIHRpZHltb2RlbHMgcGFja2FnZSBjb2xsZWN0aW9uLCB3aGljaCBpbmNsdWRlcyBwYXJzbmlwLCBoYXMgb3RoZXIgcGFja2FnZXMgZm9yIG1hbnkgb2YgdGhlc2UgdGFza3MsIGFuZCB0aGV5IGFyZSBkZXNpZ25lZCB0byB3b3JrIHRvZ2V0aGVyLiBXZSBhcmUgd29ya2luZyB0b3dhcmRzIGhpZ2hlci1sZXZlbCBBUElzIHRoYXQgY2FuIHJlcGxpY2F0ZSBhbmQgZXh0ZW5kIHdoYXQgdGhlIGN1cnJlbnQgbW9kZWwgcGFja2FnZXMgY2FuIGRvLiIKClRoZXJlIGFyZSBtYW55IFIgcGFja2FnZXMgaW4gdGhlIGB0aWR5bW9kZWxzYCBlY29zeXN0ZW0sIHdoaWNoIGFzc2lzdCB3aXRoIHZhcmlvdXMgc3RlcHMgaW4gdGhlIHByb2Nlc3Mgb2YgYnVpbGRpbmcgYSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobS4gVGhlc2UgYXJlIHRoZSBtYWluIHBhY2thZ2VzLCBidXQgdGhlcmUgYXJlIG90aGVycy4KCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwic2ltcGxldGlkeW1vZGVscy5wbmciKSkKYGBgCgpUaGlzIGlzIGEgc2NoZW1hdGljIG9mIGhvdyB0aGVzZSBwYWNrYWdlcyB3b3JrIHRvZ2V0aGVyIHRvIGJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBhbGdvcml0aG06CgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsIk1hY2hpbmVMZWFybmluZy5wbmciKSkKYGBgCgojIyMgKipCZW5lZml0cyBvZiBgdGlkeW1vZGVsc2AqKgoqKioKClRoZSB0d28gbWFqb3IgYmVuZWZpdHMgb2YgYHRpZHltb2RlbHNgIGFyZTogCgoxLiBTdGFuZGFyZGl6ZWQgd29ya2Zsb3cvZm9ybWF0L25vdGF0aW9uIGFjcm9zcyBkaWZmZXJlbnQgdHlwZXMgb2YgbWFjaGluZSBsZWFybmluZyBhbGdvcml0aG1zICAKCkRpZmZlcmVudCBub3RhdGlvbnMgYXJlIHJlcXVpcmVkIGZvciBkaWZmZXJlbnQgYWxnb3JpdGhtcyBhcyB0aGUgYWxnb3JpdGhtcyBoYXZlIGJlZW4gZGV2ZWxvcGVkIGJ5IGRpZmZlcmVudCBwZW9wbGUuIFRoaXMgd291bGQgcmVxdWlyZSB0aGUgcGFpbnN0YWtpbmcgcHJvY2VzcyBvZiByZWZvcm1hdHRpbmcgdGhlIGRhdGEgdG8gYmUgY29tcGF0aWJsZSB3aXRoIGVhY2ggYWxnb3JpdGhtIGlmIG11bHRpcGxlIGFsZ29yaXRobXMgd2VyZSB0ZXN0ZWQuCgoyLiBDYW4gZWFzaWx5IG1vZGlmeSBwcmUtcHJvY2Vzc2luZywgYWxnb3JpdGhtIGNob2ljZSwgYW5kIGh5cGVyLXBhcmFtZXRlciB0dW5pbmcgbWFraW5nIG9wdGltaXphdGlvbiBlYXN5ICAKCk1vZGlmeWluZyBhIHBpZWNlIG9mIHRoZSBvdmVyYWxsIHByb2Nlc3MgaXMgbm93IGVhc2llciB0aGFuIGJlZm9yZSBiZWNhdXNlIG1hbnkgb2YgdGhlIHN0ZXBzIGFyZSBzcGVjaWZpZWQgdXNpbmcgdGhlIGB0aWR5bW9kZWxzYCBwYWNrYWdlcyBpbiBhIGNvbnZlbmllbnQgbWFubmVyLiBUaHVzIHRoZSBlbnRpcmUgcHJvY2VzcyBjYW4gYmUgcmVydW4gYWZ0ZXIgYSBzaW1wbGUgY2hhbmdlIHRvIHByZS1wcm9jZXNzaW5nIHdpdGhvdXQgbXVjaCBkaWZmaWN1bHR5LgoKCgojIyAqKlNwbGl0dGluZyB0aGUgZGF0YSoqCioqKgoKVGhlIGZpcnN0IHN0ZXAgYWZ0ZXIgZGF0YSBleHBsb3JhdGlvbiBpbiBtYWNoaW5lIGxlYXJuaW5nIGFuYWx5c2lzIGlzIHRvIFtzcGxpdCB0aGUgZGF0YV0oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3RyYWluLXZhbGlkYXRpb24tYW5kLXRlc3Qtc2V0cy03MmNiNDBjYmE5ZTcpe3RhcmdldD0iX2JsYW5rIn0gaW50byAqKnRyYWluaW5nKiogYW5kICoqdGVzdGluZyoqIGRhdGEgc2V0cy4gCgpUaGUgdHJhaW5pbmcgZGF0YSBzZXQgd2lsbCBiZSB1c2VkIHRvIGJ1aWxkIGFuZCB0dW5lIG91ciBtb2RlbC4gClRoaXMgaXMgdGhlIGRhdGEgdGhhdCB0aGUgbW9kZWwgImxlYXJucyIgb24uIApUaGUgdGVzdGluZyBkYXRhIHNldCB3aWxsIGJlIHVzZWQgdG8gZXZhbHVhdGUgdGhlIHBlcmZvcm1hbmNlIG9mIG91ciBtb2RlbCBpbiBhIG1vcmUgZ2VuZXJhbGl6YWJsZSB3YXkuIFdoYXQgZG8gd2UgbWVhbiBieSAiZ2VuZXJhbGl6YWJsZSI/CgpSZW1lbWJlciB0aGF0IG91ciBtYWluIGdvYWwgaXMgdG8gdXNlIG91ciBtb2RlbCB0byBiZSBhYmxlIHRvIHByZWRpY3QgYWlyIHBvbGx1dGlvbiBsZXZlbHMgaW4gYXJlYXMgd2hlcmUgdGhlcmUgYXJlIG5vIGdyYXZpbWV0cmljIG1vbml0b3JzLiAKClRoZXJlZm9yZSwgaWYgb3VyIG1vZGVsIGlzIHJlYWxseSBnb29kIGF0IHByZWRpY3RpbmcgYWlyIHBvbGx1dGlvbiB3aXRoIHRoZSBkYXRhIHRoYXQgd2UgdXNlIHRvIGJ1aWxkIGl0LCBpdCBtaWdodCBub3QgZG8gdGhlIGJlc3Qgam9iIGZvciB0aGUgYXJlYXMgd2hlcmUgdGhlcmUgYXJlIGZldyB0byBubyBtb25pdG9ycy4gCgpUaGlzIHdvdWxkIGNhdXNlIHVzIHRvIGhhdmUgcmVhbGx5IGdvb2QgcHJlZGljdGlvbiBhY2N1cmFjeSBhbmQgd2UgbWlnaHQgYXNzdW1lIHRoYXQgd2Ugd2VyZSBnb2luZyB0byBkbyBhIGdvb2Qgam9iIGVzdGltYXRpbmcgYWlyIHBvbGx1dGlvbiBhbnkgdGltZSB3ZSB1c2Ugb3VyIG1vZGVsLCBidXQgaW4gZmFjdCB0aGlzIHdvdWxkIGxpa2VseSBub3QgYmUgdGhlIGNhc2UuIApUaGlzIHNpdHVhdGlvbiBpcyB3aGF0IHdlIGNhbGwgKipbb3ZlcmZpdHRpbmddKGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS90cmFpbi10ZXN0LXNwbGl0LWFuZC1jcm9zcy12YWxpZGF0aW9uLWluLXB5dGhvbi04MGI2MWJlY2E0YjYpe3RhcmdldD0iX2JsYW5rIn0gKiouCgpPdmVyZml0dGluZyBoYXBwZW5zIHdoZW4gd2UgZW5kIHVwIG1vZGVsaW5nIG5vdCBvbmx5IHRoZSBtYWpvciByZWxhdGlvbnNoaXBzIGluIG91ciBkYXRhIGJ1dCBhbHNvIHRoZSBub2lzZSB3aXRoaW4gb3VyIGRhdGEuIAoKYGBge3IsIGVjaG89RkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL21pcm8ubWVkaXVtLmNvbS9tYXgvMTExMC8xKnRCRXJYWVZ2VHcyalNVWUs3dGhVMkEucG5nIikKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vbWlyby5tZWRpdW0uY29tL21heC8xMTEwLzEqdEJFclhZVnZUdzJqU1VZSzd0aFUyQS5wbmcpe3RhcmdldD0iX2JsYW5rIn0KCklmIHdlIGdldCBnb29kIHByZWRpY3Rpb24gd2l0aCBvdXIgdGVzdGluZyBzZXQsIHRoZW4gd2Uga25vdyB0aGF0IG91ciBtb2RlbCBjYW4gYmUgYXBwbGllZCB0byBvdGhlciBkYXRhIGFuZCB3aWxsIGxpa2VseSBwZXJmb3JtIHdlbGwuIFdlIHdpbGwgZGlzY3VzcyB0aGlzIG1vcmUgbGF0ZXIuCgpXZSB3aWxsIG5vdCB0b3VjaCB0aGUgdGVzdGluZyBzZXQgdW50aWwgd2UgaGF2ZSBjb21wbGV0ZWQgb3B0aW1pemluZyBvdXIgbW9kZWwgd2l0aCB0aGUgdHJhaW5pbmcgc2V0LiAKVGhpcyB3aWxsIGFsbG93IHVzIHRvIGhhdmUgYSBsZXNzIGJpYXNlZCBldmFsdWF0aW9uIG9mIGhvdyB3ZWxsIG91ciBtb2RlbCBjYW4gZG8gd2l0aCBvdGhlciBkYXRhIGJlc2lkZXMgdGhlIGRhdGEgdXNlZCBpbiB0aGUgdHJhaW5pbmcgc2V0IHRvIGJ1aWxkIHRoZSBtb2RlbC4gCklkZWFsbHksIHlvdSB3b3VsZCBhbHNvIHdhbnQgYSBjb21wbGV0ZWx5IGluZGVwZW5kZW50IGRhdGEgc2V0IHRvIGZ1cnRoZXIgdGVzdCB0aGUgcGVyZm9ybWFuY2Ugb2YgeW91ciBtb2RlbC4KClRvIHNwbGl0IHRoZSBkYXRhIGludG8gdHJhaW5pbmcgYW5kIHRlc3RpbmcsIHdlIHdpbGwgdXNlIHRoZSBgaW5pdGlhbF9zcGxpdCgpYCBmdW5jdGlvbiBpbiB0aGUgYHJzYW1wbGVgIHBhY2thZ2UgdG8gc3BlY2lmeSBob3cgd2Ugd2FudCB0byBzcGxpdCBvdXIgZGF0YS4KCgpgYGB7ciwgZWNobz1GQUxTRX0KCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsInNwbGl0LnBuZyIpKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQpwbV9zcGxpdCA8LSByc2FtcGxlOjppbml0aWFsX3NwbGl0KGRhdGEgPSBwbSwgcHJvcCA9IDIvMykKcG1fc3BsaXQKYGBgCgpBIGNvdXBsZSBvZiBub3RlcyBmcm9tIHRoZSBjb2RlIGFib3ZlOiAKCi0gVHlwaWNhbGx5LCBkYXRhIGFyZSBzcGxpdCBpbnRvIDMvNCBvZiB0aGUgb2JzZXJ2YXRpb25zIGZvciB0cmFpbmluZyBhbmQgMS80IGZvciB0ZXN0aW5nLiBUaGlzIGlzIHRoZSBkZWZhdWx0IHByb3BvcnRpb24gYW5kIGRvZXMgbm90IG5lZWQgdG8gYmUgc3BlY2lmaWVkLiBIb3dldmVyLCB5b3UgY2FuIGNoYW5nZSB0aGUgcHJvcG9ydGlvbiB1c2luZyB0aGUgYHByb3BgIGFyZ3VtZW50LCB3aGljaCB3ZSB3aWxsIGRvIHRoYXQgaGVyZSBmb3IgaWxsdXN0cmF0aXZlIHB1cnBvc2VzLgotIFNpbmNlIHRoZSBzcGxpdCBpcyBwZXJmb3JtZWQgcmFuZG9tbHksIGl0IGlzIGEgZ29vZCBpZGVhIHRvIHVzZSB0aGUgYHNldC5zZWVkKClgIGZ1bmN0aW9uIGluIGJhc2UgUiB0byBlbnN1cmUgdGhhdCBpZiB5b3VyIHJlcnVuIHlvdXIgY29kZSB0aGF0IHlvdXIgc3BsaXQgd2lsbCBiZSB0aGUgc2FtZSBuZXh0IHRpbWUuCi0gV2UgY2FuIHNlZSB0aGUgbnVtYmVyIG9mIG1vbml0b3JzIGluIG91ciB0cmFpbmluZywgdGVzdGluZywgYW5kIG9yaWdpbmFsIGRhdGEgYnkgdHlwaW5nIGluIHRoZSBuYW1lIG9mIG91ciBzcGxpdCBvYmplY3QuIFRoZSByZXN1bHQgd2lsbCBsb29rIGxpa2UgdGhpczoKPHRyYWluaW5nIGRhdGEgc2FtcGxlIG51bWJlciwgdGVzdGluZyBkYXRhIHNhbXBsZSBudW1iZXIsIG9yaWdpbmFsIHNhbXBsZSBudW1iZXI+IAoKTm93LCB5b3UgY2FuIGFsc28gc3BlY2lmeSBhIHZhcmlhYmxlIHRvIHN0cmF0aWZ5IGJ5IHdpdGggdGhlIGBzdHJhdGFgIGFyZ3VtZW50LiAKVGhpcyBpcyB1c2VmdWwgaWYgeW91IGhhdmUgaW1iYWxhbmNlZCBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgYW5kIHlvdSB3b3VsZCBsaWtlIHRvIGludGVudGlvbmFsbHkgbWFrZSBzdXJlIHRoYXQgdGhlcmUgYXJlIHNpbWlsYXIgbnVtYmVyIG9mIHNhbXBsZXMgb2YgdGhlIHJhcmVyIGNhdGVnb3JpZXMgaW4gYm90aCB0aGUgdGVzdGluZyBhbmQgdHJhaW5pbmcgc2V0cy4gCk90aGVyd2lzZSB0aGUgc3BsaXQgaXMgcGVyZm9ybWVkIHJhbmRvbWx5LiAKCkFjY29yZGluZyB0byB0aGUgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9yc2FtcGxlL3ZlcnNpb25zLzAuMC41L3RvcGljcy9pbml0aWFsX3NwbGl0KSBmb3IgdGhlIGByc2FtcGxlYCBwYWNrYWdlOgoKPiBUaGUgc3RyYXRhIGFyZ3VtZW50IGNhdXNlcyB0aGUgcmFuZG9tIHNhbXBsaW5nIHRvIGJlIGNvbmR1Y3RlZCB3aXRoaW4gdGhlIHN0cmF0aWZpY2F0aW9uIHZhcmlhYmxlLiBUaGlzIGNhbiBoZWxwIGVuc3VyZSB0aGF0IHRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgaW4gdGhlIHRyYWluaW5nIGRhdGEgaXMgZXF1aXZhbGVudCB0byB0aGUgcHJvcG9ydGlvbnMgaW4gdGhlIG9yaWdpbmFsIGRhdGEgc2V0LgoKSW4gdGhlIGNhc2Ugd2l0aCBvdXIgZGF0YSBzZXQsIHBlcmhhcHMgd2Ugd291bGQgbGlrZSBvdXIgdHJhaW5pbmcgc2V0IHRvIGhhdmUgc2ltaWxhciBwcm9wb3J0aW9ucyBvZiBtb25pdG9ycyBmcm9tIGVhY2ggb2YgdGhlIHN0YXRlcyBhcyBpbiB0aGUgaW5pdGlhbCBkYXRhLiAKVGhpcyBtaWdodCBiZSB1c2VmdWwgaWYgd2Ugd2FudCBvdXIgbW9kZWwgdG8gYmUgZ2VuZXJhbGl6YWJsZSBhY3Jvc3MgYWxsIG9mIHRoZSBzdGF0ZXMuCgpXZSBjYW4gc2VlIHRoYXQgaW5kZWVkIHRoZXJlIGFyZSBkaWZmZXJlbnQgcHJvcG9ydGlvbnMgb2YgbW9uaXRvcnMgaW4gZWFjaCBzdGF0ZSBieSB1c2luZyB0aGUgYGNvdW50KClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2UuIAoKYGBge3IsIGV2YWwgPSBGQUxTRX0KY291bnQocG0sIHN0YXRlKQpgYGAKClNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQ6CgojIyMjIHsuc2Nyb2xsYWJsZSB9CgpgYGB7ciwgZWNobz1GQUxTRX0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpjb3VudChwbSwgc3RhdGUpICU+JQogIHByaW50KG4gPSAxZTMpCmBgYAojIyMjCgpJZiBvdXIgZGF0YSBzZXQgd2VyZSBsYXJnZSBlbm91Z2ggaXQgbWlnaHQgYmUgbmljZSB0aGVuIHRvIHN0cmF0aWZ5IGJ5IHN0YXRlIHVzaW5nIHRoZSBgc3RyYXRhID0gInN0YXRlImAgYXJndW1lbnQgaW4gYGluaXRpYWxfc3BsaXQoKWAsIGJ1dCBvdXIgZGF0YSBpcyB1bmZvcnR1bmF0ZWx5IG5vdCBsYXJnZSBlbm91Z2guIAoKSW1wb3J0YW50bHkgdGhlIGBpbml0aWFsX3NwbGl0KClgIGZ1bmN0aW9uIG9ubHkgZGV0ZXJtaW5lcyB3aGF0IHJvd3Mgb2Ygb3VyIGBwbWAgZGF0YSBmcmFtZSBzaG91bGQgYmUgYXNzaWduZWQgZm9yIHRyYWluaW5nIG9yIHRlc3RpbmcsIGl0IGRvZXMgbm90IGFjdHVhbGx5IHNwbGl0IHRoZSBkYXRhLiAKClRvIGV4dHJhY3QgdGhlIHRlc3RpbmcgYW5kIHRyYWluaW5nIGRhdGEgd2UgY2FuIHVzZSB0aGUgYHRyYWluaW5nKClgIGFuZCBgdGVzdGluZygpYCBmdW5jdGlvbnMgYWxzbyBvZiB0aGUgYHJzYW1wbGVgIHBhY2thZ2UuCgojIyMjIHsuc2Nyb2xsYWJsZSB9CmBgYHtyfQp0cmFpbl9wbSA8LXJzYW1wbGU6OnRyYWluaW5nKHBtX3NwbGl0KQp0ZXN0X3BtIDwtcnNhbXBsZTo6dGVzdGluZyhwbV9zcGxpdCkKIAojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCmNvdW50KHRyYWluX3BtLCBzdGF0ZSkKY291bnQodGVzdF9wbSwgc3RhdGUpCmBgYAojIyMjCgoKCiMjICoqUHJlcGFyaW5nIGZvciBwcmUtcHJvY2Vzc2luZyB0aGUgZGF0YSoqCioqKgoKQWZ0ZXIgc3BsaXR0aW5nIHRoZSBkYXRhLCB0aGUgbmV4dCBzdGVwIGlzIHRvIHByb2Nlc3MgdGhlIHRyYWluaW5nIGFuZCB0ZXN0aW5nIGRhdGEgc28gdGhhdCB0aGUgZGF0YSBhcmUgYXJlIGNvbXBhdGlibGUgYW5kIG9wdGltaXplZCB0byBiZSB1c2VkIHdpdGggdGhlIG1vZGVsLiAKVGhpcyBpbnZvbHZlcyBhc3NpZ25pbmcgdmFyaWFibGVzIHRvIHNwZWNpZmljIHJvbGVzIHdpdGhpbiB0aGUgbW9kZWwgYW5kIHByZS1wcm9jZXNzaW5nIGxpa2Ugc2NhbGluZyB2YXJpYWJsZXMgYW5kIHJlbW92aW5nIHJlZHVuZGFudCB2YXJpYWJsZXMuIApUaGlzIHByb2Nlc3MgaXMgYWxzbyBjYWxsZWQgZmVhdHVyZSBlbmdpbmVlcmluZy4KClRvIGRvIHRoaXMgaW4gYHRpZHltb2RlbHNgLCB3ZSB3aWxsIGNyZWF0ZSB3aGF0J3MgY2FsbGVkIGEgInJlY2lwZSIgdXNpbmcgdGhlIGByZWNpcGVzYCBwYWNrYWdlLCB3aGljaCBpcyBhIHN0YW5kYXJkaXplZCBmb3JtYXQgZm9yIGEgc2VxdWVuY2Ugb2Ygc3RlcHMgZm9yIHByZS1wcm9jZXNzaW5nIHRoZSBkYXRhLgpUaGlzIGNhbiBiZSB2ZXJ5IHVzZWZ1bCBiZWNhdXNlIGl0IG1ha2VzIHRlc3Rpbmcgb3V0IGRpZmZlcmVudCBwcmUtcHJvY2Vzc2luZyBzdGVwcyBvciBkaWZmZXJlbnQgYWxnb3JpdGhtcyB3aXRoIHRoZSBzYW1lIHByZS1wcm9jZXNzaW5nIHZlcnkgZWFzeSBhbmQgcmVwcm9kdWNpYmxlLgpDcmVhdGluZyBhIHJlY2lwZSBzcGVjaWZpZXMgKipob3cgYSBkYXRhIGZyYW1lIG9mIHByZWRpY3RvcnMgc2hvdWxkIGJlIGNyZWF0ZWQqKiAtIGl0IHNwZWNpZmllcyB3aGF0IHZhcmlhYmxlcyB0byBiZSB1c2VkIGFuZCB0aGUgcHJlLXByb2Nlc3Npbmcgc3RlcHMsIGJ1dCBpdCAqKmRvZXMgbm90IGV4ZWN1dGUgdGhlc2Ugc3RlcHMqKiBvciBjcmVhdGUgdGhlIGRhdGEgZnJhbWUgb2YgcHJlZGljdG9ycy4KCiMjIyBTdGVwIDE6IFNwZWNpZnkgdmFyaWFibGVzIHJvbGVzIHdpdGggYHJlY2lwZSgpYCBmdW5jdGlvbgoKVGhlIGZpcnN0IHRoaW5nIHRvIGRvIHRvIGNyZWF0ZSBhIHJlY2lwZSBpcyB0byBzcGVjaWZ5IHdoaWNoIHZhcmlhYmxlcyB3ZSB3aWxsIGJlIHVzaW5nIGFzIG91ciBvdXRjb21lIGFuZCBwcmVkaWN0b3JzIHVzaW5nIHRoZSBgcmVjaXBlKClgIGZ1bmN0aW9uLiAKSW4gdGVybXMgb2YgdGhlIG1ldGFwaG9yIG9mIGJha2luZywgd2UgY2FuIHRoaW5rIG9mIHRoaXMgYXMgbGlzdGluZyBvdXIgaW5ncmVkaWVudHMuIApUcmFuc2xhdGluZyB0aGlzIHRvIHRoZSBgcmVjaXBlc2AgcGFja2FnZSwgd2UgdXNlIHRoZSBgcmVjaXBlKClgIGZ1bmN0aW9uIHRvIGFzc2lnbiByb2xlcyB0byBhbGwgdGhlIHZhcmlhYmxlcy4gCgpMZXQncyB0cnkgdGhlIHNpbXBsZXN0IHJlY2lwZSB3aXRoIG5vIHByZS1wcm9jZXNzaW5nIHN0ZXBzOiBzaW1wbHkgbGlzdCB0aGUgb3V0Y29tZSBhbmQgcHJlZGljdG9yIHZhcmlhYmxlcy4KCldlIGNhbiBkbyBzbyBpbiB0d28gd2F5czogIAoKMSkgVXNpbmcgZm9ybXVsYSBub3RhdGlvbiAgCjIpIEFzc2lnbmluZyByb2xlcyB0byBlYWNoIHZhcmlhYmxlICAKCkxldCdzIGxvb2sgYXQgdGhlIGZpcnN0IHdheSB1c2luZyBmb3JtdWxhIG5vdGF0aW9uLCB3aGljaCBsb29rcyBsaWtlIHRoaXM6ICAKCm91dGNvbWUocykgfiBwcmVkaWN0b3IocykgIAoKSWYgaW4gdGhlIGNhc2Ugb2YgbXVsdGlwbGUgcHJlZGljdG9ycyBvciBhIG11bHRpdmFyaWF0ZSBzaXR1YXRpb24gd2l0aCB0d28gb3V0Y29tZXMsIHVzZSBhIHBsdXMgc2lnbjogIAoKb3V0Y29tZTEgKyBvdXRjb21lMiB+IHByZWRpY3RvcjEgKyBwcmVkaWN0b3IyICAKCklmIHdlIHdhbnQgdG8gaW5jbHVkZSBhbGwgcHJlZGljdG9ycyB3ZSBjYW4gdXNlIGEgcGVyaW9kIGxpa2Ugc286ICAKCm91dGNvbWVfdmFyaWFibGVfbmFtZSB+IC4gIAoKTm93IHdpdGggb3VyIGRhdGEsIHdlIHdpbGwgc3RhcnQgYnkgbWFraW5nIGEgcmVjaXBlIGZvciBvdXIgdHJhaW5pbmcgZGF0YS4KSWYgeW91IHJlY2FsbCwgdGhlIGNvbnRpbnVvdXMgb3V0Y29tZSB2YXJpYWJsZSBpcyBgdmFsdWVgICh0aGUgYXZlcmFnZSBhbm51YWwgZ3JhdmltZXRyaWMgbW9uaXRvciBQTX4yLjV+IGNvbmNlbnRyYXRpb24gaW4gdWcvbV4zXikuIApPdXIgZmVhdHVyZXMgKG9yIHByZWRpY3RvciB2YXJpYWJsZXMpIGFyZSBhbGwgdGhlIG90aGVyIHZhcmlhYmxlcyBleGNlcHQgdGhlIG1vbml0b3IgSUQsIHdoaWNoIGlzIGFuIGBpZGAgdmFyaWFibGUuCgpUaGUgcmVhc29uIG5vdCB0byBpbmNsdWRlIHRoZSBgaWRgIHZhcmlhYmxlIGlzIGJlY2F1c2UgdGhpcyB2YXJpYWJsZSBpbmNsdWRlcyB0aGUgY291bnR5IG51bWJlciBhbmQgYSBudW1iZXIgZGVzaWduYXRpbmcgd2hpY2ggcGFydGljdWxhciBtb25pdG9yIHRoZSB2YWx1ZXMgY2FtZSBmcm9tIChvZiB0aGUgbW9uaXRvcnMgdGhlcmUgYXJlIGluIHRoYXQgY291bnR5KS4gClNpbmNlIHRoaXMgbnVtYmVyIGlzIGFyYml0cmFyeSBhbmQgdGhlIGNvdW50eSBpbmZvcm1hdGlvbiBpcyBhbHNvIGdpdmVuIGluIHRoZSBkYXRhLCBhbmQgdGhlIGZhY3QgdGhhdCBlYWNoIG1vbml0b3Igb25seSBoYXMgb25lIHZhbHVlIGluIHRoZSBgdmFsdWVgIHZhcmlhYmxlLCBub3RoaW5nIGlzIGdhaW5lZCBieSBpbmNsdWRpbmcgdGhpcyB2YXJpYWJsZSBhbmQgaXQgbWF5IGluc3RlYWQgaW50cm9kdWNlIG5vaXNlLiAKSG93ZXZlciwgaXQgaXMgdXNlZnVsIHRvIGtlZXAgdGhpcyBkYXRhIHRvIHRha2UgYSBsb29rIGF0IHdoYXQgaXMgaGFwcGVuaW5nIGxhdGVyLiAKV2Ugd2lsbCBzaG93IHlvdSB3aGF0IHRvIGRvIGluIHRoaXMgY2FzZSBpbiBqdXN0IGEgYml0LgoKSW4gdGhlIHNpbXBsZXN0IGNhc2UsIHdlIG1pZ2h0IHVzZSBhbGwgcHJlZGljdG9ycyBsaWtlIHRoaXM6CgpgYGB7cn0Kc2ltcGxlX3JlYyA8LSB0cmFpbl9wbSAlPiUKICByZWNpcGVzOjpyZWNpcGUodmFsdWUgfiAuKQoKc2ltcGxlX3JlYwpgYGAKCldlIHNlZSBhIHJlY2lwZSBoYXMgYmVlbiBjcmVhdGVkIHdpdGggMSBvdXRjb21lIHZhcmlhYmxlIGFuZCA0OSBwcmVkaWN0b3IgdmFyaWFibGVzIChvciBmZWF0dXJlcykuIApBbHNvLCBub3RpY2UgaG93IHdlIG5hbWVkIHRoZSBvdXRwdXQgb2YgYHJlY2lwZSgpYC4gClRoZSBuYW1pbmcgY29udmVudGlvbiBmb3IgcmVjaXBlIG9iamVjdHMgaXMgYCpfcmVjYCBvciBgcmVjYC4gCgpOb3csIGxldCdzIGdldCBiYWNrIHRvIHRoZSBgaWRgIHZhcmlhYmxlLiAKSW5zdGVhZCBvZiBpbmNsdWRpbmcgaXQgYXMgYSBwcmVkaWN0b3IgdmFyaWFibGUsIHdlIGNvdWxkIGFsc28gdXNlIHRoZSBgdXBkYXRlX3JvbGUoKWAgZnVuY3Rpb24gb2YgdGhlIGByZWNpcGVzYCBwYWNrYWdlLgoKYGBge3J9CnNpbXBsZV9yZWMgPC0gdHJhaW5fcG0gJT4lCiAgcmVjaXBlczo6cmVjaXBlKHZhbHVlIH4gLikgJT4lCiAgcmVjaXBlczo6dXBkYXRlX3JvbGUoaWQsIG5ld19yb2xlID0gImlkIHZhcmlhYmxlIikKCnNpbXBsZV9yZWMKYGBgCgo8ZGV0YWlscz48c3VtbWFyeT4gQ2xpY2sgaGVyZSBsZWFybiBtb3JlIGFib3V0IHRoZSB3b3JraW5nIHdpdGggYGlkYCB2YXJpYWJsZXMgPC9zdW1tYXJ5PgoKVGhpcyBvcHRpb24gd29ya3Mgd2VsbCB3aXRoIHRoZSBuZXdlciBgd29ya2Zsb3dzYCBwYWNrYWdlLCBob3dldmVyIGBpZGAgdmFyaWFibGVzIGFyZSBvZnRlbiBkcm9wcGVkIGZyb20gYW5hbHlzZXMgdGhhdCBkbyBub3QgdXNlIHRoaXMgbmV3ZXIgcGFja2FnZSBhcyB0aGV5IGNhbiBtYWtlIHRoZSBwcm9jZXNzIGRpZmZpY3VsdCB3aXRoIHVzaW5nIHRoZSBgcGFyc25pcGAgcGFja2FnZSBhbG9uZSBkdWUgdG8gdGhlIGZhY3QgdGhhdCBuZXcgbGV2ZWxzIChvciBwb3NzaWJsZSB2YWx1ZXMpIG1heSBiZSBpbnRyb2R1Y2VkIHdpdGggdGhlIHRlc3RpbmcgZGF0YS4KCjwvZGV0YWlscz4KCldlIGNvdWxkIGFsc28gc3BlY2lmeSB0aGUgb3V0Y29tZSBhbmQgcHJlZGljdG9ycyBpbiB0aGUgc2FtZSB3YXkgYXMgd2UganVzdCBzcGVjaWZpZWQgdGhlIGlkIHZhcmlhYmxlLiAKUGxlYXNlIHNlZSBbaGVyZV0oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby9yZWNpcGVzL3JlZmVyZW5jZS9yZWNpcGUuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgZXhhbXBsZXMgb2Ygb3RoZXIgcm9sZXMgZm9yIHZhcmlhYmxlcy4gClRoZSByb2xlIGNhbiBiZSBhY3R1YWxseSBiZSBhbnkgdmFsdWUuIAoKVGhlIG9yZGVyIGlzIGltcG9ydGFudCBoZXJlLCBhcyB3ZSBmaXJzdCBtYWtlIGFsbCB2YXJpYWJsZXMgcHJlZGljdG9ycyBhbmQgdGhlbiBvdmVycmlkZSB0aGlzIHJvbGUgZm9yIHRoZSBvdXRjb21lIGFuZCBgaWRgIHZhcmlhYmxlLiAKV2Ugd2lsbCB1c2UgdGhlIGBldmVyeXRoaW5nKClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2UgdG8gc3RhcnQgd2l0aCBhbGwgb2YgdGhlIHZhcmlhYmxlcyBpbiBgdHJhaW5fcG1gLgoKYGBge3J9CnNpbXBsZV9yZWMgPC1yZWNpcGUodHJhaW5fcG0pICU+JQogICAgdXBkYXRlX3JvbGUoZXZlcnl0aGluZygpLCBuZXdfcm9sZSA9ICJwcmVkaWN0b3IiKSU+JQogICAgdXBkYXRlX3JvbGUodmFsdWUsIG5ld19yb2xlID0gIm91dGNvbWUiKSU+JQogICAgdXBkYXRlX3JvbGUoaWQsIG5ld19yb2xlID0gImlkIHZhcmlhYmxlIikKCnNpbXBsZV9yZWMKYGBgCgpJZiB3ZSB3YW50IHRvIHRha2UgYSBsb29rIGF0IG91ciBmb3JtdWxhIGZyb20gb3VyIHJlY2lwZSwgd2UgY2FuIGRvIHVzZSB0aGUgYGZvcm11bGEoKWAgZnVuY3Rpb24gb2YgdGhlIGBzdGF0c2AgcGFja2FnZS4KCmBgYHtyfQpmb3JtdWxhKHNpbXBsZV9yZWMpCmBgYAoKV2UgY2FuIGFsc28gdmlldyBvdXIgcmVjaXBlIGluIG1vcmUgZGV0YWlsIHVzaW5nIHRoZSBiYXNlIGBzdW1tYXJ5KClgIGZ1bmN0aW9uLgoKYGBge3J9CnN1bW1hcnkoc2ltcGxlX3JlYykKYGBgCgpUbyBzdW1tYXJpemUgdGhpcyBzdGVwLCB3ZSB1c2UgdGhlIGByZWNpcGUoKWAgZnVuY3Rpb24gdG8gYXNzaWduIHJvbGVzIHRvIGFsbCB0aGUgdmFyaWFibGVzOiAKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjQwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwiU3RhcnRpbmdfYV9yZWNpcGVfcmVjaXBlczEucG5nIikpCmBgYAoKCiMjIyBTdGVwIDI6IFNwZWNpZnkgdGhlIHByZS1wcm9jZXNzaW5nIHN0ZXBzIHdpdGggYHN0ZXAqKClgIGZ1bmN0aW9ucwoKTmV4dCwgd2UgdXNlIHRoZSBgc3RlcCooKWAgZnVuY3Rpb25zIGZyb20gdGhlIGByZWNpcGVgIHBhY2thZ2UgdG8gc3BlY2lmeSBwcmUtcHJvY2Vzc2luZyBzdGVwcy4gCgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI0MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsIk1ha2luZ19hX3JlY2lwZV9yZWNpcGVzMi5wbmciKSkKYGBgCgoqKlRoaXMgW2xpbmtdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcmVjaXBlcy9yZWZlcmVuY2UvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSBhbmQgdGhpcyBbbGlua10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3JlY2lwZXMvcmVjaXBlcy5wZGYpe3RhcmdldD0iX2JsYW5rIn0gc2hvdyB0aGUgbWFueSBvcHRpb25zIGZvciByZWNpcGUgc3RlcCBmdW5jdGlvbnMuKioKCjx1PlRoZXJlIGFyZSBzdGVwIGZ1bmN0aW9ucyBmb3IgYSB2YXJpZXR5IG9mIHB1cnBvc2VzOjwvdT4KCjEuIFsqKkltcHV0YXRpb24qKl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW1wdXRhdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gLS0gZmlsbGluZyBpbiBtaXNzaW5nIHZhbHVlcyBiYXNlZCBvbiB0aGUgZXhpc3RpbmcgZGF0YSAKMi4gWyoqVHJhbnNmb3JtYXRpb24qKl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRGF0YV90cmFuc2Zvcm1hdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gLS0gY2hhbmdpbmcgYWxsIHZhbHVlcyBvZiBhIHZhcmlhYmxlIGluIHRoZSBzYW1lIHdheSwgdHlwaWNhbGx5IHRvIG1ha2UgaXQgbW9yZSBub3JtYWwgb3IgZWFzaWVyIHRvIGludGVycHJldAozLiBbKipEaXNjcmV0aXphdGlvbioqXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EaXNjcmV0aXphdGlvbl9vZl9jb250aW51b3VzX2ZlYXR1cmVzKXt0YXJnZXQ9Il9ibGFuayJ9IC0tIGNvbnZlcnRpbmcgY29udGludW91cyB2YWx1ZXMgaW50byBkaXNjcmV0ZSBvciBub21pbmFsIHZhbHVlcyAtIGJpbm5pbmcgZm9yIGV4YW1wbGUgdG8gcmVkdWNlIHRoZSBudW1iZXIgb2YgcG9zc2libGUgbGV2ZWxzIChIb3dldmVyIHRoaXMgaXMgZ2VuZXJhbGx5IG5vdCBhZHZpc2FibGUhKQo0LiBbKipFbmNvZGluZyAvIENyZWF0aW5nIER1bW15IFZhcmlhYmxlcyoqXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EdW1teV92YXJpYWJsZV8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gLS0gY3JlYXRpbmcgYSBudW1lcmljIGNvZGUgZm9yIGNhdGVnb3JpY2FsIHZhcmlhYmxlcwooWyoqTW9yZSBvbiBEdW1teSBWYXJpYWJsZXMgYW5kIG9uZSBob3QgZW5jb2RpbmcqKl0oaHR0cHM6Ly9tZWRpdW0uY29tL3AvYjU4NDBiZTNjNDFhL3Jlc3BvbnNlcy9zaG93KXt0YXJnZXQ9Il9ibGFuayJ9KQo1LiBbKipEYXRhIHR5cGUgY29udmVyc2lvbnMqKl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2hhYmxhci92aWduZXR0ZXMvY29udmVydC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAtLSB3aGljaCBtZWFucyBjaGFuZ2luZyBmcm9tIGludGVnZXIgdG8gZmFjdG9yIG9yIG51bWVyaWMgdG8gZGF0ZSBldGMuCjYuIFsqKkludGVyYWN0aW9uKipdKGh0dHBzOi8vc3RhdGlzdGljc2J5amltLmNvbS9yZWdyZXNzaW9uL2ludGVyYWN0aW9uLWVmZmVjdHMvKXt0YXJnZXQ9Il9ibGFuayJ9ICB0ZXJtIGFkZGl0aW9uIHRvIHRoZSBtb2RlbCAtLSB3aGljaCBtZWFucyB0aGF0IHdlIHdvdWxkIGJlIG1vZGVsaW5nIGZvciBwcmVkaWN0b3JzIHRoYXQgd291bGQgaW5mbHVlbmNlIHRoZSBjYXBhY2l0eSBvZiBlYWNoIG90aGVyIHRvIHByZWRpY3QgdGhlIG91dGNvbWUKNy4gWyoqTm9ybWFsaXphdGlvbioqXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Ob3JtYWxpemF0aW9uXyhzdGF0aXN0aWNzKSl7dGFyZ2V0PSJfYmxhbmsifSAtLSBjZW50ZXJpbmcgYW5kIHNjYWxpbmcgdGhlIGRhdGEgdG8gYSBzaW1pbGFyIHJhbmdlIG9mIHZhbHVlcwo4LiBbKipEaW1lbnNpb25hbGl0eSBSZWR1Y3Rpb24vIFNpZ25hbCBFeHRyYWN0aW9uKipdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0RpbWVuc2lvbmFsaXR5X3JlZHVjdGlvbil7dGFyZ2V0PSJfYmxhbmsifSAtLSByZWR1Y2luZyB0aGUgc3BhY2Ugb2YgZmVhdHVyZXMgb3IgcHJlZGljdG9ycyB0byBhIHNtYWxsZXIgc2V0IG9mIHZhcmlhYmxlcyB0aGF0IGNhcHR1cmUgdGhlIHZhcmlhdGlvbiBvciBzaWduYWwgaW4gdGhlIG9yaWdpbmFsIHZhcmlhYmxlcyAoZXguIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMgYW5kIEluZGVwZW5kZW50IENvbXBvbmVudCBBbmFseXNpcykKOS4gKipGaWx0ZXJpbmcqKiAtLSBmaWx0ZXJpbmcgb3B0aW9ucyBmb3IgcmVtb3ZpbmcgdmFyaWFibGVzIChleC4gcmVtb3ZlIHZhcmlhYmxlcyB0aGF0IGFyZSBoaWdobHkgY29ycmVsYXRlZCB0byBvdGhlcnMgb3IgcmVtb3ZlIHZhcmlhYmxlcyB3aXRoIHZlcnkgbGl0dGxlIHZhcmlhbmNlIGFuZCB0aGVyZWZvcmUgbGlrZWx5IGxpdHRsZSBwcmVkaWN0aXZlIGNhcGFjaXR5KQoxMC4gWyoqUm93IG9wZXJhdGlvbnMqKl0oaHR0cHM6Ly90YXJ0YXJ1cy5vcmcvZ2FyZXRoL21hdGhzL0xpbmVhcl9BbGdlYnJhL3Jvd19vcGVyYXRpb25zLnBkZil7dGFyZ2V0PSJfYmxhbmsifSAtLSBwZXJmb3JtaW5nIGZ1bmN0aW9ucyBvbiB0aGUgdmFsdWVzIHdpdGhpbiB0aGUgcm93cyAgKGV4LiByZWFycmFuZ2luZywgZmlsdGVyaW5nLCBpbXB1dGluZykKMTEuICoqQ2hlY2tpbmcgZnVuY3Rpb25zKiogLS0gU2FuaXR5IGNoZWNrcyB0byBsb29rIGZvciBtaXNzaW5nIHZhbHVlcywgdG8gbG9vayBhdCB0aGUgdmFyaWFibGUgY2xhc3NlcyBldGMuCgpBbGwgb2YgdGhlIHN0ZXAgZnVuY3Rpb25zIGxvb2sgbGlrZSBgc3RlcF8qKClgIHdpdGggdGhlIGAqYCByZXBsYWNlZCB3aXRoIGEgbmFtZSwgZXhjZXB0IGZvciB0aGUgY2hlY2sgZnVuY3Rpb25zIHdoaWNoIGxvb2sgbGlrZSBgY2hlY2tfKigpYC4KClRoZXJlIGFyZSBzZXZlcmFsIHdheXMgdG8gc2VsZWN0IHdoYXQgdmFyaWFibGVzIHRvIGFwcGx5IHN0ZXBzIHRvOiAgCgoxLiBVc2luZyBgdGlkeXNlbGVjdGAgbWV0aG9kczogYGNvbnRhaW5zKClgLCBgbWF0Y2hlcygpYCwgYHN0YXJ0c193aXRoKClgLCBgZW5kc193aXRoKClgLCBgZXZlcnl0aGluZygpYCwgYG51bV9yYW5nZSgpYCAgCjIuIFVzaW5nIHRoZSB0eXBlOiBgYWxsX25vbWluYWwoKWAsIGBhbGxfbnVtZXJpYygpYCAsIGBoYXNfdHlwZSgpYCAKMy4gVXNpbmcgdGhlIHJvbGU6IGBhbGxfcHJlZGljdG9ycygpYCwgYGFsbF9vdXRjb21lcygpYCwgYGhhc19yb2xlKClgCjQuIFVzaW5nIHRoZSBuYW1lIC0gdXNlIHRoZSBhY3R1YWwgbmFtZSBvZiB0aGUgdmFyaWFibGUvdmFyaWFibGVzIG9mIGludGVyZXN0ICAKCkxldCdzIHRyeSBhZGRpbmcgc29tZSBzdGVwcyB0byBvdXIgcmVjaXBlLgoKCldlIG1pZ2h0IHdhbnQgdG8gcG90ZW50aWFsbHkgW29uZSBob3QgZW5jb2RlXShodHRwczovL21hY2hpbmVsZWFybmluZ21hc3RlcnkuY29tL3doeS1vbmUtaG90LWVuY29kZS1kYXRhLWluLW1hY2hpbmUtbGVhcm5pbmcvKXt0YXJnZXQ9Il9ibGFuayJ9IHNvbWUgb2Ygb3VyIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBzbyB0aGF0IHRoZXkgY2FuIGJlIHVzZWQgd2l0aCBjZXJ0YWluIGFsZ29yaXRobXMuIAoKV2UgY2FuIGRvIHRoaXMgd2l0aCB0aGUgYHN0ZXBfZHVtbXkoKWAgZnVuY3Rpb24gYW5kIHRoZSBgb25lX2hvdCA9IFRSVUVgIGFyZ3VtZW50LiAKT25lIGhvdCBlbmNvZGluZyBtZWFucyB0aGF0IHdlIGRvIG5vdCBzaW1wbHkgZW5jb2RlIG91ciBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgbnVtZXJpY2FsbHksIGFzIG91ciBudW1lcmljIGFzc2lnbm1lbnRzIGNhbiBiZSBpbnRlcnByZXRlZCBieSBhbGdvcml0aG1zIGFzIGhhdmluZyBhIHBhcnRpY3VsYXIgcmFuayBvciBvcmRlci4gCkluc3RlYWQsIGJpbmFyeSB2YXJpYWJsZXMgbWFkZSBvZiAxcyBhbmQgMHMgYXJlIHVzZWQgdG8gYXJiaXRyYXJpbHkgYXNzaWduIGEgbnVtZXJpYyB2YWx1ZSB0aGF0IGhhcyBubyBhcHBhcmVudCBvcmRlci4KCmBgYHtyfQpzaW1wbGVfcmVjICU+JQogIHN0ZXBfZHVtbXkoc3RhdGUsIGNvdW50eSwgY2l0eSwgemN0YSwgb25lX2hvdCA9IFRSVUUpCmBgYAoKT3VyIGBmaXBzYCB2YXJpYWJsZSBpbmNsdWRlcyBhIG51bWVyaWMgY29kZSBmb3Igc3RhdGUgYW5kIGNvdW50eSAtIGFuZCB0aGVyZWZvcmUgaXMgZXNzZW50aWFsbHkgYSBwcm94eSBmb3IgY291bnR5LgpTaW5jZSB3ZSBhbHJlYWR5IGhhdmUgY291bnR5LCB3ZSB3aWxsIGp1c3QgdXNlIGl0IGFuZCBrZWVwIHRoZSBgZmlwc2AgSUQgYXMgYW5vdGhlciBJRCB2YXJpYWJsZS4KCldlIGNhbiByZW1vdmUgdGhlIGBmaXBzYCB2YXJpYWJsZSBmcm9tIHRoZSBwcmVkaWN0b3JzIHVzaW5nIGB1cGRhdGVfcm9sZSgpYCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgcm9sZSBpcyBubyBsb25nZXIgYCJwcmVkaWN0b3IiYC4gCldlIGNhbiBtYWtlIHRoZSByb2xlIGFueXRoaW5nIHdlIHdhbnQgYWN0dWFsbHksIHNvIHdlIHdpbGwga2VlcCBpdCBzb21ldGhpbmcgaWRlbnRpZmlhYmxlLgoKYGBge3J9CnNpbXBsZV9yZWMgJT4lCiAgdXBkYXRlX3JvbGUoImZpcHMiLCBuZXdfcm9sZSA9ICJjb3VudHkgaWQiKQpgYGAKCldlIG1pZ2h0IGFsc28gd2FudCB0byByZW1vdmUgdmFyaWFibGVzIHRoYXQgYXBwZWFyIHRvIGJlIHJlZHVuZGFudCBhbmQgYXJlIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggb3RoZXJzLCBhcyB3ZSBrbm93IGZyb20gb3VyIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgdGhhdCBtYW55IG9mIG91ciB2YXJpYWJsZXMgYXJlIGNvcnJlbGF0ZWQgd2l0aCBvbmUgYW5vdGhlci4gCldlIGNhbiBkbyB0aGlzIHVzaW5nIHRoZSBgc3RlcF9jb3JyKClgIGZ1bmN0aW9uLgoKV2UgZG9uJ3Qgd2FudCB0byByZW1vdmUgc29tZSBvZiBvdXIgdmFyaWFibGVzLCBsaWtlIHRoZSBgQ01BUWAgYW5kIGBhb2RgIHZhcmlhYmxlcywgd2UgY2FuIHNwZWNpZnkgdGhpcyB1c2luZyB0aGUgYC1gIHNpZ24gYmVmb3JlIHRoZSBuYW1lcyBvZiB0aGVzZSB2YXJpYWJsZXMgbGlrZSBzbzoKCmBgYHtyfQpzaW1wbGVfcmVjICU+JQogIHN0ZXBfY29ycihhbGxfcHJlZGljdG9ycygpLCAtIENNQVEsIC0gYW9kKQpgYGAKCgpJdCBpcyBhbHNvIGEgZ29vZCBpZGVhIHRvIHJlbW92ZSB2YXJpYWJsZXMgd2l0aCBuZWFyLXplcm8gdmFyaWFuY2UsIHdoaWNoIGNhbiBiZSBkb25lIHdpdGggdGhlIGBzdGVwX256digpYCBmdW5jdGlvbi4gCgpWYXJpYWJsZXMgaGF2ZSBsb3cgdmFyaWFuY2UgaWYgYWxsIHRoZSB2YWx1ZXMgYXJlIHZlcnkgc2ltaWxhciwgdGhlIHZhbHVlcyBhcmUgdmVyeSBzcGFyc2UsIG9yIGlmIHRoZXkgYXJlIGhpZ2hseSBpbWJhbGFuY2VkLiBBZ2FpbiB3ZSBkb24ndCB3YW50IHRvIHJlbW92ZSBvdXIgYENNQVFgIGFuZCBgYW9kYCB2YXJpYWJsZXMuCgpgYGB7cn0Kc2ltcGxlX3JlYyAlPiUKICBzdGVwX256dihhbGxfcHJlZGljdG9ycygpLCAtIENNQVEsIC0gYW9kKQpgYGAKCjxkZXRhaWxzPjxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIGxlYXJuIGFib3V0IGV4YW1wbGVzIHdoZXJlIHlvdSBtaWdodCBoYXZlIG5lYXItemVybyB2YXJpYW5jZSB2YXJpYWJsZXM8L3N1bW1hcnk+CgoxKSAqKlNpbWlsYXIgVmFsdWVzKiogLSBJZiB0aGUgcG9wdWxhdGlvbiBkZW5zaXR5IHdhcyBuZWFybHkgdGhlIHNhbWUgZm9yIGV2ZXJ5IHpjdGEgdGhhdCBjb250YWluZWQgYSBtb25pdG9yLCB0aGVuIGtub3dpbmcgdGhlIHBvcHVsYXRpb24gZGVuc2l0eSBuZWFyIG91ciBtb25pdG9yIHdvdWxkIGNvbnRyaWJ1dGUgbGl0dGxlIHRvIG91ciBtb2RlbCBpbiBhc3Npc3RpbmcgdXMgdG8gcHJlZGljdCBtb25pdG9yIGFpciBwb2xsdXRpb24gdmFsdWVzLiAKMikgKipTcGFyc2UgRGF0YSoqIC0gSWYgYWxsIG9mIHRoZSBtb25pdG9ycyB3ZXJlIGluIGxvY2F0aW9ucyB3aGVyZSB0aGUgcG9wdWxhdGlvbnMgZGlkIG5vdCBhdHRlbmQgZ3JhZHVhdGUgc2Nob29sLCB0aGVuIHRoZXNlIHZhbHVlcyB3b3VsZCBtb3N0bHkgYmUgemVybywgYWdhaW4gdGhpcyB3b3VsZCBkbyB2ZXJ5IGxpdHRsZSB0byBoZWxwIHVzIGRpc3Rpbmd1aXNoIG91ciBhaXIgcG9sbHV0aW9uIG1vbml0b3JzLldoZW4gbWFueSBvZiB0aGUgdmFsdWVzIGFyZSB6ZXJvIHRoaXMgaXMgYWxzbyBjYWxsZWQgc3BhcnNlIGRhdGEuICAKMykgKipJbWJhbGFuY2VkIERhdGEqKiBJZiBuZWFybHkgYWxsIG9mIHRoZSBtb25pdG9ycyB3ZXJlIGxvY2F0ZWQgaW4gb25lIHBhcnRpY3VsYXIgc3RhdGUsIGFuZCBhbGwgdGhlIG90aGVycyBvbmx5IGhhZCBvbmUgbW9uaXRvciBlYWNoLCB0aGVuIHRoZSByZWFsIHByZWRpY3RpdmUgdmFsdWUgd291bGQgc2ltcGx5IGJlIGluIGtub3dpbmcgaWYgYSBtb25pdG9yIGlzIGxvY2F0ZWQgaW4gdGhhdCBwYXJ0aWN1bGFyIHN0YXRlIG9yIG5vdC4gSW4gdGhpcyBjYXNlIHdlIGRvbid0IHdhbnQgdG8gcmVtb3ZlIG91ciB2YXJpYWJsZSwgd2UganVzdCB3YW50IHRvIHNpbXBsaWZ5IGl0LgoKU2VlIHRoaXMgW2Jsb2cgcG9zdF0oaHR0cHM6Ly93d3cuci1ibG9nZ2Vycy5jb20vbmVhci16ZXJvLXZhcmlhbmNlLXByZWRpY3RvcnMtc2hvdWxkLXdlLXJlbW92ZS10aGVtLyl7dGFyZ2V0PSJfYmxhbmsifSBhYm91dCB3aHkgcmVtb3ZpbmcgbmVhci16ZXJvIHZhcmlhbmNlIHZhcmlhYmxlcyBpc24ndCBhbHdheXMgYSBnb29kIGlkZWEgaWYgd2UgdGhpbmsgdGhhdCBhIHZhcmlhYmxlIG1pZ2h0IGJlIGVzcGVjaWFsbHkgaW5mb3JtYXRpdmUuCgo8L2RldGFpbHM+CgpMZXQncyBwdXQgYWxsIHRoaXMgdG9nZXRoZXIgbm93LiAKCioqUmVtZW1iZXI6IGl0IGlzIGltcG9ydGFudCB0byBhZGQgdGhlIHN0ZXBzIHRvIHRoZSByZWNpcGUgaW4gYW4gb3JkZXIgdGhhdCBtYWtlcyBzZW5zZSBqdXN0IGxpa2Ugd2l0aCBhIGNvb2tpbmcgcmVjaXBlLioqCgpGaXJzdCwgd2UgYXJlIGdvaW5nIHRvIGNyZWF0ZSBudW1lcmljIHZhbHVlcyBmb3Igb3VyIGNhdGVnb3JpY2FsIHZhcmlhYmxlcywgdGhlbiB3ZSB3aWxsIGxvb2sgYXQgY29ycmVsYXRpb24gYW5kIG5lYXItemVybyB2YXJpYW5jZS4gCkFnYWluLCB3ZSBkbyBub3Qgd2FudCB0byByZW1vdmUgdGhlIGBDTUFRYCBhbmQgYGFvZGAgdmFyaWFibGVzLCBzbyB3ZSBjYW4gbWFrZSBzdXJlIHRoZXkgYXJlIGtlcHQgaW4gdGhlIG1vZGVsIGJ5IGV4Y2x1ZGluZyB0aGVtIGZyb20gdGhvc2Ugc3RlcHMuIApJZiB3ZSBzcGVjaWZpY2FsbHkgd2FudGVkIHRvIHJlbW92ZSBhIHByZWRpY3RvciB3ZSBjb3VsZCB1c2UgYHN0ZXBfcm0oKWAuCgpgYGB7cn0Kc2ltcGxlX3JlYyAlPD4lCiAgdXBkYXRlX3JvbGUoImZpcHMiLCBuZXdfcm9sZSA9ICJjb3VudHkgaWQiKSAlPiUKICBzdGVwX2R1bW15KHN0YXRlLCBjb3VudHksIGNpdHksIHpjdGEsIG9uZV9ob3QgPSBUUlVFKSAlPiUKICBzdGVwX2NvcnIoYWxsX3ByZWRpY3RvcnMoKSwgLSBDTUFRLCAtIGFvZCklPiUKICBzdGVwX256dihhbGxfcHJlZGljdG9ycygpLCAtIENNQVEsIC0gYW9kKQogIApzaW1wbGVfcmVjCmBgYAoKCgojIyAqKlJ1bm5pbmcgdGhlIHByZS1wcm9jZXNzaW5nKioKKioqCgojIyMgKipTdGVwIDE6IFVwZGF0ZSB0aGUgcmVjaXBlIHdpdGggdHJhaW5pbmcgZGF0YSB1c2luZyBgcHJlcCgpYCoqCioqKgoKVGhlIG5leHQgbWFqb3IgZnVuY3Rpb24gb2YgdGhlIGByZWNpcGVzYCBwYWNrYWdlIGlzIGBwcmVwKClgLgpUaGlzIGZ1bmN0aW9uIHVwZGF0ZXMgdGhlIHJlY2lwZSBvYmplY3QgYmFzZWQgb24gdGhlIHRyYWluaW5nIGRhdGEuIApJdCBlc3RpbWF0ZXMgcGFyYW1ldGVycyAoZXN0aW1hdGluZyB0aGUgcmVxdWlyZWQgcXVhbnRpdGllcyBhbmQgc3RhdGlzdGljcyByZXF1aXJlZCBieSB0aGUgc3RlcHMgZm9yIHRoZSB2YXJpYWJsZXMpIGZvciBwcmUtcHJvY2Vzc2luZyBhbmQgdXBkYXRlcyB0aGUgdmFyaWFibGVzIHJvbGVzLCBhcyBzb21lIG9mIHRoZSBwcmVkaWN0b3JzIG1heSBiZSByZW1vdmVkLCB0aGlzIGFsbG93cyB0aGUgcmVjaXBlIHRvIGJlIHJlYWR5IHRvIHVzZSBvbiBvdGhlciBkYXRhIHNldHMuIApJdCAqKmRvZXMgbm90IG5lY2Vzc2FyaWx5IGFjdHVhbGx5IGV4ZWN1dGUgdGhlIHByZS1wcm9jZXNzaW5nIGl0c2VsZioqLCBob3dldmVyIHdlIHdpbGwgc3BlY2lmeSBpbiBhcmd1bWVudCBmb3IgaXQgdG8gZG8gdGhpcyBzbyB0aGF0IHdlIGNhbiB0YWtlIGEgbG9vayBhdCB0aGUgcHJlLXByb2Nlc3NlZCBkYXRhLgoKClRoZXJlIGFyZSBzb21lIGltcG9ydGFudCBhcmd1bWVudHMgdG8ga25vdyBhYm91dDoKCjEuIGB0cmFpbmluZ2AgLSB5b3UgbXVzdCBzdXBwbHkgYSB0cmFpbmluZyBkYXRhIHNldCB0byBlc3RpbWF0ZSBwYXJhbWV0ZXJzIGZvciBwcmUtcHJvY2Vzc2luZyBvcGVyYXRpb25zIChyZWNpcGUgc3RlcHMpIC0gdGhpcyBtYXkgYWxyZWFkeSBiZSBpbmNsdWRlZCBpbiB5b3VyIHJlY2lwZSAtIGFzIGlzIHRoZSBjYXNlIGZvciB1cwoyLiBgZnJlc2hgIC0gaWYgYGZyZXNoPVRSVUVgLCAtIHdpbGwgcmV0cmFpbiBhbmQgZXN0aW1hdGUgcGFyYW1ldGVycyBmb3IgYW55IHByZXZpb3VzIHN0ZXBzIHRoYXQgd2VyZSBhbHJlYWR5IHByZXBwZWQgaWYgeW91IGFkZCBtb3JlIHN0ZXBzIHRvIHRoZSByZWNpcGUKMy4gYHZlcmJvc2VgIC0gaWYgYHZlcmJvc2U9VFJVRWAsIHNob3dzIHRoZSBwcm9ncmVzcyBhcyB0aGUgc3RlcHMgYXJlIGV2YWx1YXRlZCBhbmQgdGhlIHNpemUgb2YgdGhlIHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgc2V0CjQuIGByZXRhaW5gIC0gaWYgYHJldGFpbj1UUlVFYCwgdGhlbiB0aGUgcHJlLXByb2Nlc3NlZCB0cmFpbmluZyBzZXQgd2lsbCBiZSBzYXZlZCB3aXRoaW4gdGhlIHJlY2lwZSAoYXMgdGVtcGxhdGUpLiBUaGlzIGlzIGdvb2QgaWYgeW91IGFyZSBsaWtlbHkgdG8gYWRkIG1vcmUgc3RlcHMgYW5kIGRvIG5vdCB3YW50IHRvIHJlcnVuIHRoZSBgcHJlcCgpYCBvbiB0aGUgcHJldmlvdXMgc3RlcHMuIEhvd2V2ZXIgdGhpcyBjYW4gbWFrZSB0aGUgcmVjaXBlIHNpemUgbGFyZ2UuIFRoaXMgaXMgbmVjZXNzYXJ5IGlmIHlvdSB3YW50IHRvIGFjdHVhbGx5IGxvb2sgYXQgdGhlIHByZS1wcm9jZXNzZWQgZGF0YS4KCkxldCdzIHRyeSBvdXQgdGhlIGBwcmVwKClgIGZ1bmN0aW9uOiAKCmBgYHtyfQpwcmVwcGVkX3JlYyA8LSBwcmVwKHNpbXBsZV9yZWMsIHZlcmJvc2UgPSBUUlVFLCByZXRhaW4gPSBUUlVFICkKbmFtZXMocHJlcHBlZF9yZWMpCmBgYAoKVGhlcmUgYXJlIGFsc28gbG90cyBvZiB1c2VmdWwgdGhpbmdzIHRvIGNoZWNrb3V0IGluIHRoZSBvdXRwdXQgb2YgYHByZXAoKWAuCllvdSBjYW4gc2VlOgoKMS4gdGhlIGBzdGVwc2AgdGhhdCB3ZXJlIHJ1biAgCjIuIHRoZSBvcmlnaW5hbCB2YXJpYWJsZSBpbmZvIChgdmFyX2luZm9gKSAgCjMuIHRoZSB1cGRhdGVkIHZhcmlhYmxlIGluZm8gYWZ0ZXIgcHJlLXByb2Nlc3NpbmcgKGB0ZXJtX2luZm9gKQo0LiB0aGUgbmV3IGBsZXZlbHNgIG9mIHRoZSB2YXJpYWJsZXMgCjUuIHRoZSBvcmlnaW5hbCBsZXZlbHMgb2YgdGhlIHZhcmlhYmxlcyAoYG9yaWdfbHZsc2ApCjYuIGluZm8gYWJvdXQgdGhlIHRyYWluaW5nIGRhdGEgc2V0IHNpemUgYW5kIGNvbXBsZXRlbmVzcyAoYHRyX2luZm9gKQoKKipOb3RlKio6IFlvdSBtYXkgc2VlIHRoZSBgcHJlcC5yZWNpcGUoKWAgZnVuY3Rpb24gaW4gbWF0ZXJpYWwgdGhhdCB5b3UgcmVhZCBhYm91dCB0aGUgYHJlY2lwZXNgIHBhY2thZ2UuIFRoaXMgaXMgcmVmZXJyaW5nIHRvIHRoZSBgcHJlcCgpYCBmdW5jdGlvbiBvZiB0aGUgYHJlY2lwZXNgIHBhY2thZ2UuCgoKIyMjICoqU3RlcCAyOiBFeHRyYWN0IHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YSB1c2luZyBgYmFrZSgpYCoqCioqKgoKClNpbmNlIHdlIHJldGFpbmVkIG91ciBwcmUtcHJvY2Vzc2VkIHRyYWluaW5nIGRhdGEgKGkuZS4gYHByZXAocmV0YWluPVRSVUUpYCksIHdlIGNhbiB0YWtlIGEgbG9vayBhdCBpdCBsaWtlIGJ5IHVzaW5nIHRoZSBgYmFrZSgpYCBmdW5jdGlvbiBvZiB0aGUgYHJlY2lwZXNgIHBhY2thZ2UgbGlrZSB0aGlzOgoKYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iNDAwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCJ0cmFpbmluZ19wcmVwcm9jZXNzaW5nX3JlY2lwZXMzLnBuZyIpKQpgYGAKCkxldCdzIGJha2UhIAoKU2luY2Ugd2UgZG9uJ3QgaGF2ZSBuZXcgZGF0YSAod2UgYXJlbid0IGxvb2tpbmcgYXQgdGhlIHRlc3RpbmcgZGF0YSksIHdlIG5lZWQgdG8gc3BlY2lmeSB0aGlzIHdpdGggYG5ld19kYXRhID0gTlVMTGAuCgojIyMjIHsuc2Nyb2xsYWJsZSB9CmBgYHtyfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCmJha2VkX3RyYWluIDwtIGJha2UocHJlcHBlZF9yZWMsIG5ld19kYXRhID0gTlVMTCkKZ2xpbXBzZShiYWtlZF90cmFpbikKYGBgCiMjIyMKCioqTm90ZSoqLSB0aGlzIHByb2Nlc3MgdXNlZCB0byByZXF1aXJlIHRoZSBganVpY2UoKWAgZnVuY3Rpb24uCgpGb3IgZWFzeSBjb21wYXJpc29uIHNha2UgLSBoZXJlIGlzIG91ciBvcmlnaW5hbCBkYXRhOgoKIyMjIyB7LnNjcm9sbGFibGUgfQoKYGBge3J9CiMgU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dCEKZ2xpbXBzZShwbSkKYGBgCiMjIyMKCk5vdGljZSBob3cgd2Ugb25seSBoYXZlIDM2IHZhcmlhYmxlcyBub3cgaW5zdGVhZCBvZiA1MCEgClR3byBvZiB0aGVzZSBhcmUgb3VyIElEIHZhcmlhYmxlcyAoYGZpcHNgIGFuZCB0aGUgYWN0dWFsIG1vbml0b3IgSUQgKGBpZGApKSBhbmQgb25lIGlzIG91ciBvdXRjb21lIChgdmFsdWVgKS4gClRodXMgd2Ugb25seSBoYXZlIDMzIHByZWRpY3RvcnMgbm93LiAKV2UgY2FuIGFsc28gc2VlIHRoYXQgd2Ugbm8gbG9uZ2VyIGhhdmUgYW55IGNhdGVnb3JpY2FsIHZhcmlhYmxlcy4gClZhcmlhYmxlcyBsaWtlIGBzdGF0ZWAgYXJlIGdvbmUgYW5kIG9ubHkgYHN0YXRlX0NhbGlmb3JuaWFgIHJlbWFpbnMgYXMgaXQgd2FzIHRoZSBvbmx5IHN0YXRlIGlkZW50aXR5IHRvIGhhdmUgbm9uemVybyB2YXJpYW5jZS4KV2UgY2FuIGFsc28gc2VlIHRoYXQgdGhlcmUgd2VyZSBtb3JlIG1vbml0b3JzIGxpc3RlZCBhcyBgIk5vdCBpbiBhIGNpdHkiYCB0aGFuIGFueSBjaXR5LiAKCldlIGNhbiBzZWUgdGhhdCBDYWxpZm9ybmlhIGhhZCB0aGUgbGFyZ2VzdCBudW1iZXIgb2YgbW9uaXRvcnMgY29tcGFyZWQgdG8gdGhlIG90aGVyIHN0YXRlcy4KCmBgYHtyLCBldmFsID0gRkFMU0V9CnBtICU+JSBjb3VudChzdGF0ZSkgCmBgYAoKClNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQ6CgojIyMjIHsuc2Nyb2xsYWJsZSB9CgpgYGB7ciwgZWNobyA9IEZBTFNFfQpwbSAlPiUgY291bnQoc3RhdGUpICAlPiUKICBwcmludChuID0gMWUzKQpgYGAKCiMjIyMKCmBgYHtyLCBldmFsID0gRkFMU0V9CnBtICU+JSBjb3VudChjaXR5KQpgYGAKClNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQ6CgojIyMjIHsuc2Nyb2xsYWJsZSB9CgpgYGB7ciwgZWNobz1GQUxTRX0KcG0gJT4lIGNvdW50KGNpdHkpICU+JQogIHByaW50KG4gPSAxZTMpCmBgYAoKIyMjIwoKKipOb3RlKio6IFJlY2FsbCB0aGF0IHlvdSBtdXN0IHNwZWNpZnkgYHJldGFpbiA9IFRSVUVgIGFyZ3VtZW50IG9mIHRoZSBgcHJlcCgpYCBmdW5jdGlvbiB0byB1c2UgYGJha2UoKWAuCgojIyMgKipTdGVwIDM6IEV4dHJhY3QgcHJlLXByb2Nlc3NlZCB0ZXN0aW5nIGRhdGEgdXNpbmcgYGJha2UoKWAqKgoqKioKCkFjY29yZGluZyB0byB0aGUgYHRpZHltb2RlbHNgIGRvY3VtZW50YXRpb246Cgo+IGBiYWtlKClgIHRha2VzIGEgdHJhaW5lZCByZWNpcGUgYW5kIGFwcGxpZXMgdGhlIG9wZXJhdGlvbnMgdG8gYSBkYXRhIHNldCB0byBjcmVhdGUgYSBkZXNpZ24gbWF0cml4LgogRm9yIGV4YW1wbGU6IGl0IGFwcGxpZXMgdGhlIGNlbnRlcmluZyB0byBuZXcgZGF0YSBzZXRzIHVzaW5nIHRoZXNlIG1lYW5zIHVzZWQgdG8gY3JlYXRlIHRoZSByZWNpcGUuCgpUaGVyZWZvcmUsIGlmIHlvdSB3YW50ZWQgdG8gbG9vayBhdCB0aGUgcHJlLXByb2Nlc3NlZCB0ZXN0aW5nIGRhdGEgeW91IHdvdWxkIHVzZSB0aGUgYGJha2UoKWAgZnVuY3Rpb24gb2YgdGhlIGByZWNpcGVzYCBwYWNrYWdlLgooWW91IGdlbmVyYWxseSB3YW50IHRvIGxlYXZlIHlvdXIgdGVzdGluZyBkYXRhIGFsb25lLCBidXQgaXQgaXMgZ29vZCB0byBsb29rIGZvciBpc3N1ZXMgbGlrZSB0aGUgaW50cm9kdWN0aW9uIG9mIE5BIHZhbHVlcykuCgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI0MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsInRlc3RpbmdfcHJlcHJvY2Vzc2luZ19yZWNpcGVzNC5wbmciKSkKYGBgCgpMZXQncyBiYWtlISAKCiMjIyMgey5zY3JvbGxhYmxlIH0KYGBge3IsfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCmJha2VkX3Rlc3RfcG0gPC0gcmVjaXBlczo6YmFrZShwcmVwcGVkX3JlYywgbmV3X2RhdGEgPSB0ZXN0X3BtKQpnbGltcHNlKGJha2VkX3Rlc3RfcG0pCmBgYAojIyMjCgoKTm90aWNlIHRoYXQgb3VyIGBjaXR5X05vdC5pbi5hLmNpdHlgIHZhcmlhYmxlIHNlZW1zIHRvIGJlIE5BIHZhbHVlcy4gCldoeSBtaWdodCB0aGF0IGJlPwoKQWghIFBlcmhhcHMgaXQgaXMgYmVjYXVzZSBzb21lIG9mIG91ciBsZXZlbHMgd2VyZSBub3QgcHJldmlvdXNseSBzZWVuIGluIHRoZSB0cmFpbmluZyBzZXQhCgpMZXQncyB0YWtlIGEgbG9vayB1c2luZyB0aGUgW3NldCBvcGVyYXRpb25zXShodHRwczovL3d3dy5wcm9iYWJpbGl0eWNvdXJzZS5jb20vY2hhcHRlcjEvMV8yXzJfc2V0X29wZXJhdGlvbnMucGhwKXt0YXJnZXQ9Il9ibGFuayJ9IG9mIHRoZSBgZHBseXJgIHBhY2thZ2UuIApXZSBjYW4gdGFrZSBhIGxvb2sgYXQgY2l0aWVzIHRoYXQgd2VyZSBkaWZmZXJlbnQgYmV0d2VlbiB0aGUgdGVzdCBhbmQgdHJhaW5pbmcgc2V0LgoKYGBge3J9CnRyYWluY2l0aWVzIDwtIHRyYWluX3BtICU+JSBkaXN0aW5jdChjaXR5KQp0ZXN0Y2l0aWVzIDwtIHRlc3RfcG0gJT4lIGRpc3RpbmN0KGNpdHkpCgojZ2V0IHRoZSBudW1iZXIgb2YgY2l0aWVzIHRoYXQgd2VyZSBkaWZmZXJlbnQKZGltKGRwbHlyOjpzZXRkaWZmKHRyYWluY2l0aWVzLCB0ZXN0Y2l0aWVzKSkKCiNnZXQgdGhlIG51bWJlciBvZiBjaXRpZXMgdGhhdCBvdmVybGFwcGVkCmRpbShkcGx5cjo6aW50ZXJzZWN0KHRyYWluY2l0aWVzLCB0ZXN0Y2l0aWVzKSkKYGBgCgpJbmRlZWQsIHRoZXJlIGFyZSBsb3RzIG9mIGRpZmZlcmVudCBjaXRpZXMgaW4gb3VyIHRlc3QgZGF0YSB0aGF0IGFyZSBub3QgaW4gb3VyIHRyYWluaW5nIGRhdGEhCgoKU28sIGxldCBnbyBiYWNrIHRvIG91ciBgcG1gIGRhdGEgc2V0IGFuZCBtb2RpZnkgdGhlIGBjaXR5YCB2YXJpYWJsZSB0byBqdXN0IGJlIHZhbHVlcyBvZiBgaW4gYSBjaXR5YCBvciBgbm90IGluIGEgY2l0eWAgdXNpbmcgdGhlIGBjYXNlX3doZW4oKWAgZnVuY3Rpb24gb2YgYGRwbHlyYC4KVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHZlY3Rvcml6ZSBtdWx0aXBsZSBgaWZfZWxzZSgpYCBzdGF0ZW1lbnRzLgoKYGBge3J9CnBtICU+JQogIG11dGF0ZShjaXR5ID0gY2FzZV93aGVuKGNpdHkgPT0gIk5vdCBpbiBhIGNpdHkiIH4gIk5vdCBpbiBhIGNpdHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNpdHkgIT0gIk5vdCBpbiBhIGNpdHkiIH4gIkluIGEgY2l0eSIpKQpgYGAKCkFsdGVybmF0aXZlbHkgeW91IGNvdWxkIGNyZWF0ZSBhIFtjdXN0b20gc3RlcCBmdW5jdGlvbl0oaHR0cHM6Ly9yZWNpcGVzLnRpZHltb2RlbHMub3JnL2FydGljbGVzL0N1c3RvbV9TdGVwcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9IHRvIGRvIHRoaXMgYW5kIGFkZCB0aGlzIHRvIHlvdXIgcmVjaXBlLCBidXQgdGhhdCBpcyBiZXlvbmQgdGhlIHNjb3BlIG9mIHRoaXMgY2FzZSBzdHVkeS4gCgpXZSB3aWxsIG5lZWQgdG8gcmVwZWF0IGFsbCB0aGUgc3RlcHMgKHNwbGl0dGluZyB0aGUgZGF0YSwgcHJlLXByb2Nlc3NpbmcsIGV0YykgYXMgdGhlIGxldmVscyBvZiBvdXIgdmFyaWFibGVzIGhhdmUgbm93IGNoYW5nZWQuIAoKV2hpbGUgd2UgYXJlIGRvaW5nIHRoaXMsIHdlIG1pZ2h0IGFsc28gaGF2ZSB0aGlzIGlzc3VlIGZvciBgY291bnR5YC4gCgpUaGUgYGNvdW50eWAgdmFyaWFibGVzIGFwcGVhcnMgdG8gZ2V0IGRyb3BwZWQgZHVlIHRvIGVpdGhlciBjb3JyZWxhdGlvbiBvciBuZWFyIHplcm8gdmFyaWFuY2UuIAoKSXQgaXMgbGlrZWx5IGR1ZSB0byBuZWFyIHplcm8gdmFyaWFuY2UgYmVjYXVzZSB0aGlzIGlzIHRoZSBtb3JlIGdyYW51bGFyIG9mIHRoZXNlIGdlb2dyYXBoaWMgY2F0ZWdvcmljYWwgdmFyaWFibGVzIGFuZCBsaWtlbHkgc3BhcnNlLgoKYGBge3J9CnBtICU8PiUKICBtdXRhdGUoY2l0eSA9IGNhc2Vfd2hlbihjaXR5ID09ICJOb3QgaW4gYSBjaXR5IiB+ICJOb3QgaW4gYSBjaXR5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaXR5ICE9ICJOb3QgaW4gYSBjaXR5IiB+ICJJbiBhIGNpdHkiKSkKCnNldC5zZWVkKDEyMzQpICMgc2FtZSBzZWVkIGFzIGJlZm9yZQpwbV9zcGxpdCA8LXJzYW1wbGU6OmluaXRpYWxfc3BsaXQoZGF0YSA9IHBtLCBwcm9wID0gMi8zKQpwbV9zcGxpdAogdHJhaW5fcG0gPC1yc2FtcGxlOjp0cmFpbmluZyhwbV9zcGxpdCkKIHRlc3RfcG0gPC1yc2FtcGxlOjp0ZXN0aW5nKHBtX3NwbGl0KQpgYGAKCgojIyMjIHsucmVjYWxsX2NvZGVfcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBRdWVzdGlvbiBPcHBvcnR1bml0eSA8L3U+PC9iPgoKU2VlIGlmIHlvdSBjYW4gY29tZSB1cCB3aXRoIHRoZSBjb2RlIGZvciB0aGUgbmV3IHJlY2lwZS4KCiMjIyMKCioqKgoKPGRldGFpbHM+IDxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHJldmVhbCB0aGUgY29kZSBmb3IgdGhlIG5ldyByZWNpcGUuIDwvc3VtbWFyeT4KCgpgYGB7cn0Kbm92ZWxfcmVjIDwtcmVjaXBlKHRyYWluX3BtKSAlPiUKICAgIHVwZGF0ZV9yb2xlKGV2ZXJ5dGhpbmcoKSwgbmV3X3JvbGUgPSAicHJlZGljdG9yIikgJT4lCiAgICB1cGRhdGVfcm9sZSh2YWx1ZSwgbmV3X3JvbGUgPSAib3V0Y29tZSIpICU+JQogICAgdXBkYXRlX3JvbGUoaWQsIG5ld19yb2xlID0gImlkIHZhcmlhYmxlIikgJT4lCiAgICB1cGRhdGVfcm9sZSgiZmlwcyIsIG5ld19yb2xlID0gImNvdW50eSBpZCIpICU+JQogICAgc3RlcF9kdW1teShzdGF0ZSwgY291bnR5LCBjaXR5LCB6Y3RhLCBvbmVfaG90ID0gVFJVRSkgJT4lCiAgICBzdGVwX2NvcnIoYWxsX251bWVyaWMoKSkgJT4lCiAgICBzdGVwX256dihhbGxfbnVtZXJpYygpKSAKYGBgCjwvZGV0YWlscz4KKioqCgpgYGB7cn0Kbm92ZWxfcmVjCmBgYAoKCgpOb3cgbGV0J3MgcmV0cmFpbiBvdXIgdHJhaW5pbmcgZGF0YSBhbmQgdHJ5IGJha2luZyBvdXIgdGVzdCBkYXRhLgoKCgojIyMjIHsucmVjYWxsX2NvZGVfcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBRdWVzdGlvbiBPcHBvcnR1bml0eSA8L3U+PC9iPgoKRG8geW91IHJlY2FsbCBob3cgdG8gcHJlLXByb2Nlc3MgYW5kIGV4dHJhY3QgdGhlIHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YT8KCiMjIyMKCioqKgoKPGRldGFpbHM+IDxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHJldmVhbCB0aGUgYW5zd2VyLiA8L3N1bW1hcnk+CgpgYGB7cn0KcHJlcHBlZF9yZWMgPC0gcHJlcChub3ZlbF9yZWMsIHZlcmJvc2UgPSBUUlVFLCByZXRhaW4gPSBUUlVFKQpiYWtlZF90cmFpbiA8LSBiYWtlKHByZXBwZWRfcmVjLCBuZXdfZGF0YSA9IE5VTEwpCmBgYAo8L2RldGFpbHM+IAoqKioKCgojIyMjIHsuc2Nyb2xsYWJsZSB9CmBgYHtyfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCmdsaW1wc2UoYmFrZWRfdHJhaW4pCmBgYAoKIyMjIwoKQW5kIG5vdywgbGV0J3MgdHJ5IGJha2luZyBvdXIgdGVzdCBzZXQgdG8gc2VlIGlmIHdlIHN0aWxsIGhhdmUgYE5BYCB2YWx1ZXMuCgojIyMjIHsuc2Nyb2xsYWJsZSB9CgpgYGB7cn0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpiYWtlZF90ZXN0X3BtIDwtIHJlY2lwZXM6OmJha2UocHJlcHBlZF9yZWMsIG5ld19kYXRhID0gdGVzdF9wbSkKCmdsaW1wc2UoYmFrZWRfdGVzdF9wbSkKYGBgCgojIyMjCgpHcmVhdCwgbm93IHdlIG5vIGxvbmdlciBoYXZlIGBOQWAgdmFsdWVzISA6KQoKKipOb3RlKio6IGlmIHlvdSB1c2UgdGhlIHNraXAgb3B0aW9uIGZvciBzb21lIG9mIHRoZSBwcmUtcHJvY2Vzc2luZyBzdGVwcywgYmUgY2FyZWZ1bC4gCmBqdWljZSgpYCB3aWxsIHNob3cgYWxsIG9mIHRoZSByZXN1bHRzIGlnbm9yaW5nIGBza2lwID0gVFJVRWAgKGFzIHlvdSBjYW4gc3RpbGwgdXNlIHRoaXMgZnVuY3Rpb24gaWYgeW91IHBlcmZlciBpdCB0byBgYmFrZSgpYCkuCmBiYWtlKClgIHdpbGwgbm90IG5lY2Vzc2FyaWx5IGNvbmR1Y3QgdGhlc2Ugc3RlcHMgb24gdGhlIG5ldyBkYXRhLgoKCiMjICoqU3BlY2lmeWluZyB0aGUgbW9kZWwqKgoqKioKClNvIGZhciB3ZSBoYXZlIHVzZWQgdGhlIHBhY2thZ2VzIGByc2FtcGxlYCB0byBzcGxpdCB0aGUgZGF0YSBhbmQgYHJlY2lwZXNgIHRvIGFzc2lnbiB2YXJpYWJsZSB0eXBlcywgYW5kIHRvIHNwZWNpZnkgYW5kIHByZXAgb3VyIHByZS1wcm9jZXNzaW5nIChhcyB3ZWxsIGFzIHRvIG9wdGlvbmFsbHkgZXh0cmFjdCB0aGUgcHJlLXByb2Nlc3NlZCBkYXRhKS4KCldlIHdpbGwgbm93IHVzZSB0aGUgYHBhcnNuaXBgIHBhY2thZ2UgKHdoaWNoIGlzIHNpbWlsYXIgdG8gdGhlIHByZXZpb3VzIGBjYXJldGAgcGFja2FnZSAtIGFuZCBoZW5jZSB3aHkgaXQgaXMgbmFtZWQgYWZ0ZXIgdGhlIHZlZ2V0YWJsZSkgdG8gc3BlY2lmeSBvdXIgbW9kZWwuCgpUaGVyZSBhcmUgZm91ciB0aGluZ3Mgd2UgbmVlZCB0byBkZWZpbmUgYWJvdXQgb3VyIG1vZGVsOiAgCgoxLiBUaGUgKip0eXBlKiogb2YgbW9kZWwgKHVzaW5nIHNwZWNpZmljIGZ1bmN0aW9ucyBpbiBwYXJzbmlwIGxpa2UgYHJhbmRfZm9yZXN0KClgLCBgbG9naXN0aWNfcmVnKClgIGV0Yy4pICAKMi4gVGhlIHBhY2thZ2Ugb3IgKiplbmdpbmUqKiB0aGF0IHdlIHdpbGwgdXNlIHRvIGltcGxlbWVudCB0aGUgdHlwZSBvZiBtb2RlbCBzZWxlY3RlZCAodXNpbmcgdGhlIGBzZXRfZW5naW5lKClgIGZ1bmN0aW9uKSAKMy4gVGhlICoqbW9kZSoqIG9mIGxlYXJuaW5nIC0gY2xhc3NpZmljYXRpb24gb3IgcmVncmVzc2lvbiAodXNpbmcgdGhlIGBzZXRfbW9kZSgpYCBmdW5jdGlvbikgCjQuIEFueSAqKmFyZ3VtZW50cyoqIG5lY2Vzc2FyeSBmb3IgdGhlIG1vZGVsL3BhY2thZ2Ugc2VsZWN0ZWQgKHVzaW5nIHRoZSBgc2V0X2FyZ3MoKWBmdW5jdGlvbiAtICBmb3IgZXhhbXBsZSB0aGUgYG10cnkgPWAgYXJndW1lbnQgZm9yIHJhbmRvbSBmb3Jlc3Qgd2hpY2ggaXMgdGhlIG51bWJlciBvZiB2YXJpYWJsZXMgdG8gYmUgdXNlZCBhcyBvcHRpb25zIGZvciBzcGxpdHRpbmcgYXQgZWFjaCB0cmVlIG5vZGUpCgpMZXQncyB3YWxrIHRocm91Z2ggdGhlc2Ugc3RlcHMgb25lIGJ5IG9uZS4gCkZvciBvdXIgY2FzZSwgd2UgYXJlIGdvaW5nIHRvIHN0YXJ0IG91ciBhbmFseXNpcyB3aXRoIGEgbGluZWFyIHJlZ3Jlc3Npb24gYnV0IHdlIHdpbGwgZGVtb25zdHJhdGUgaG93IHdlIGNhbiB0cnkgZGlmZmVyZW50IG1vZGVscy4KClRoZSBmaXJzdCBzdGVwIGlzIHRvIGRlZmluZSB3aGF0IHR5cGUgb2YgbW9kZWwgd2Ugd291bGQgbGlrZSB0byB1c2UuIApTZWUgW2hlcmVdKGh0dHBzOi8vd3d3LnRpZHltb2RlbHMub3JnL2ZpbmQvcGFyc25pcC8pe3RhcmdldD0iX2JsYW5rIn0gZm9yIG1vZGVsaW5nIG9wdGlvbnMgaW4gYHBhcnNuaXBgLgoKCmBgYHtyfQpQTV9tb2RlbCA8LSBwYXJzbmlwOjpsaW5lYXJfcmVnKCkgIyBQTSB3YXMgdXNlZCBpbiB0aGUgbmFtZSBmb3IgcGFydGljdWxhdGUgbWF0dGVyClBNX21vZGVsCmBgYAoKT0suIFNvIGZhciwgYWxsIHdlIGhhdmUgZGVmaW5lZCBpcyB0aGF0IHdlIHdhbnQgdG8gdXNlIGEgbGluZWFyIHJlZ3Jlc3Npb24uLi4gIApMZXQncyB0ZWxsIGBwYXJzbmlwYCBtb3JlIGFib3V0IHdoYXQgd2Ugd2FudC4KCldlIHdvdWxkIGxpa2UgdG8gdXNlIHRoZSBbb3JkaW5hcnkgbGVhc3Qgc3F1YXJlc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvT3JkaW5hcnlfbGVhc3Rfc3F1YXJlcykgbWV0aG9kIHRvIGZpdCBvdXIgbGluZWFyIHJlZ3Jlc3Npb24uIApTbyB3ZSB3aWxsIHRlbGwgYHBhcnNuaXBgIHRoYXQgd2Ugd2FudCB0byB1c2UgdGhlIGBsbWAgcGFja2FnZSB0byBpbXBsZW1lbnQgb3VyIGxpbmVhciByZWdyZXNzaW9uICh0aGVyZSBhcmUgbWFueSBvcHRpb25zIGFjdHVhbGx5IHN1Y2ggYXMgW2Byc3RhbmBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yc3Rhbi92aWduZXR0ZXMvcnN0YW4uaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgW2BnbG1uZXRgXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ2xtbmV0L2luZGV4Lmh0bWwpe3RhcmdldD0iX2JsYW5rIn0sIFtga2VyYXNgXShodHRwczovL2tlcmFzLnJzdHVkaW8uY29tLyl7dGFyZ2V0PSJfYmxhbmsifSwgYW5kIFtgc3BhcmtseXJgXShodHRwczovL3RoZXJpbnNwYXJrLmNvbS9zdGFydGluZy5odG1sI3N0YXJ0aW5nLXNwYXJrbHlyLWhlbGxvLXdvcmxkKXt0YXJnZXQ9Il9ibGFuayJ9KS4gU2VlIFtoZXJlXShodHRwczovL3BhcnNuaXAudGlkeW1vZGVscy5vcmcvcmVmZXJlbmNlL2xpbmVhcl9yZWcuaHRtbCkgZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhlIGRpZmZlcmVuY2VzIGFuZCB1c2luZyB0aGVzZSBkaWZmZXJlbnQgZW5naW5lcyB3aXRoIGBwYXJzbmlwYC4KCldlIHdpbGwgZG8gc28gYnkgdXNpbmcgdGhlIGBzZXRfZW5naW5lKClgIGZ1bmN0aW9uIG9mIHRoZSBgcGFyc25pcGAgcGFja2FnZS4KCmBgYHtyfQpsbV9QTV9tb2RlbCA8LSAKICBQTV9tb2RlbCAgJT4lCiAgcGFyc25pcDo6c2V0X2VuZ2luZSgibG0iKQoKbG1fUE1fbW9kZWwKYGBgCgpJbiBzb21lIGNhc2VzIHNvbWUgcGFja2FnZXMgY2FuIGRvIGVpdGhlciBjbGFzc2lmaWNhdGlvbiBvciBwcmVkaWN0aW9uLCBzbyBpdCBpcyBhIGdvb2QgaWRlYSB0byBzcGVjaWZ5IHdoaWNoIG1vZGUgeW91IGludGVuZCB0byBwZXJmb3JtLiAKSGVyZSwgd2UgYWltIHRvIHByZWRpY3QgdGhlIGFpciBwb2xsdXRpb24uIApZb3UgY2FuIGRvIHRoaXMgd2l0aCB0aGUgYHNldF9tb2RlKClgIGZ1bmN0aW9uIG9mIHRoZSBgcGFyc25pcGAgcGFja2FnZSwgYnkgdXNpbmcgZWl0aGVyIGBzZXRfbW9kZSgiY2xhc3NpZmljYXRpb24iKWAgb3IgYHNldF9tb2RlKCJyZWdyZXNzaW9uIilgLgoKYGBge3J9CmxtX1BNX21vZGVsIDwtIAogIFBNX21vZGVsICAlPiUKICBwYXJzbmlwOjpzZXRfZW5naW5lKCJsbSIpICU+JQogIHNldF9tb2RlKCJyZWdyZXNzaW9uIikKCmxtX1BNX21vZGVsCmBgYAoKIyMgKipGaXR0aW5nIHRoZSBtb2RlbCoqCioqKgoKV2UgY2FuICB1c2UgdGhlIGBwYXJzbmlwYCBwYWNrYWdlIHdpdGggYSBuZXdlciBwYWNrYWdlIGNhbGxlZCBgd29ya2Zsb3dzYCB0byBmaXQgb3VyIG1vZGVsLiAKClRoZSBgd29ya2Zsb3dzYCBwYWNrYWdlIGFsbG93cyB1cyB0byBrZWVwIHRyYWNrIG9mIGJvdGggb3VyIHByZS1wcm9jZXNzaW5nIHN0ZXBzIGFuZCBvdXIgbW9kZWwgc3BlY2lmaWNhdGlvbi4gSXQgYWxzbyBhbGxvd3MgdXMgdG8gaW1wbGVtZW50IGZhbmNpZXIgb3B0aW1pemF0aW9ucyBpbiBhbiBhdXRvbWF0ZWQgd2F5IGFuZCBpdCBjYW4gYWxzbyBoYW5kbGUgcG9zdC1wcm9jZXNzaW5nIG9wZXJhdGlvbnMuIAoKCldlIGJlZ2luIGJ5IGNyZWF0aW5nIGEgd29ya2Zsb3cgdXNpbmcgdGhlIGB3b3JrZmxvdygpYCBmdW5jdGlvbiBpbiB0aGUgYHdvcmtmbG93c2AgcGFja2FnZS4gCgpOZXh0LCB3ZSB1c2UgYGFkZF9yZWNpcGUoKWAgKG91ciBwcmUtcHJvY2Vzc2luZyBzcGVjaWZpY2F0aW9ucykgYW5kIHdlIGFkZCBvdXIgbW9kZWwgd2l0aCB0aGUgYGFkZF9tb2RlbCgpYCBmdW5jdGlvbiAtLSBib3RoIGZ1bmN0aW9ucyBmcm9tIHRoZSBgd29ya2Zsb3dzYCBwYWNrYWdlLgoKKipOb3RlKio6IFdlIGRvIG5vdCBuZWVkIHRvIGFjdHVhbGx5IGBwcmVwKClgIG91ciByZWNpcGUgYmVmb3JlIHVzaW5nIHdvcmtmbG93cyEKCklmIHlvdSByZWNhbGwgYG5vdmVsX3JlY2AgaXMgdGhlIHJlY2lwZSB3ZSBwcmV2aW91c2x5IGNyZWF0ZWQgd2l0aCB0aGUgYHJlY2lwZXNgIHBhY2thZ2UgYW5kIGBsbV9QTV9tb2RlbGAgd2FzIGNyZWF0ZWQgd2hlbiB3ZSBzcGVjaWZpZWQgb3VyIG1vZGVsIHdpdGggdGhlIGBwYXJzbmlwYCBwYWNrYWdlLgpIZXJlLCB3ZSBjb21iaW5lIGV2ZXJ5dGhpbmcgdG9nZXRoZXIgaW50byBhIHdvcmtmbG93LiAKCmBgYHtyfQpQTV93ZmxvdyA8LXdvcmtmbG93czo6d29ya2Zsb3coKSAlPiUKICAgICAgICAgICB3b3JrZmxvd3M6OmFkZF9yZWNpcGUobm92ZWxfcmVjKSAlPiUKICAgICAgICAgICB3b3JrZmxvd3M6OmFkZF9tb2RlbChsbV9QTV9tb2RlbCkKUE1fd2Zsb3cKYGBgCgpBaCwgbmljZS4gCk5vdGljZSBob3cgaXQgdGVsbHMgdXMgYWJvdXQgYm90aCBvdXIgcHJlLXByb2Nlc3Npbmcgc3RlcHMgYW5kIG91ciBtb2RlbCBzcGVjaWZpY2F0aW9ucy4KCk5leHQsIHdlICJwcmVwYXJlIHRoZSByZWNpcGUiIChvciBlc3RpbWF0ZSB0aGUgcGFyYW1ldGVycykgYW5kIGZpdCB0aGUgbW9kZWwgdG8gb3VyIHRyYWluaW5nIGRhdGEgYWxsIGF0IG9uY2UuIApQcmludGluZyB0aGUgb3V0cHV0LCB3ZSBjYW4gc2VlIHRoZSBjb2VmZmljaWVudHMgb2YgdGhlIG1vZGVsLgoKYGBge3J9ClBNX3dmbG93X2ZpdCA8LSBwYXJzbmlwOjpmaXQoUE1fd2Zsb3csIGRhdGEgPSB0cmFpbl9wbSkKUE1fd2Zsb3dfZml0CmBgYAoKCjxkZXRhaWxzPjxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHNlZSB0aGUgc3RlcHMgdGhhdCB0aGUgYHdvcmtmbG93c2AgcGFja2FnZSBwZXJmb3JtcyB0aGF0IHVzZWQgdG8gYmUgcmVxdWlyZWQgPC9zdW1tYXJ5PgoKUHJldmlvdXNseSwgdGhlIHByb2Nlc3NlZCB0cmFpbmluZyBkYXRhIChgYmFrZWRfdHJhaW5gKSwgYXMgb3Bwb3NlZCB0byB0aGUgcmF3IHRyYWluaW5nIGRhdGEsIHdvdWxkIGJlIHJlcXVpcmVkIHRvIGZpdCB0aGUgbW9kZWwuCgpJbiB0aGlzIGNhc2UsIHdlIHdvdWxkIGFjdHVhbGx5IGFsc28gbmVlZCB0byB3cml0ZSB0aGUgbW9kZWwgYWdhaW4hIApSZWNhbGwgdGhhdCBgaWRgIGFuZCBgZmlwc2AgYXJlIElEIHZhcmlhYmxlcyBhbmQgdGhhdCBgdmFsdWVzYCBpcyBvdXIgb3V0Y29tZSBvZiBpbnRlcmVzdCAodGhlIGFpciBwb2xsdXRpb24gbWVhc3VyZSBhdCBlYWNoIG1vbml0b3IpLiBJdCBpcyBuaWNlIHRoYXQgYHdvcmtmbG93c2Aga2VlcHMgdHJhY2sgb2YgdGhpcyEKCmBgYHtyfQpiYWtlZF90cmFpbl9yZWFkeSA8LSBiYWtlZF90cmFpbiAlPiUgCiAgc2VsZWN0KC1pZCwgLWZpcHMpCgpQTV9maXQgPC0gbG1fUE1fbW9kZWwgJT4lIAogIHBhcnNuaXA6OmZpdCh2YWx1ZSB+LiwgZGF0YSA9IGJha2VkX3RyYWluX3JlYWR5KQpgYGAKCjwvZGV0YWlscz4KCiMjICoqQXNzZXNzaW5nIHRoZSBtb2RlbCBmaXQqKgoqKioKCkFmdGVyIHdlIGZpdCBvdXIgbW9kZWwsIHdlIGNhbiB1c2UgdGhlIGBicm9vbWAgcGFja2FnZSB0byBsb29rIGF0IHRoZSBvdXRwdXQgZnJvbSB0aGUgZml0dGVkIG1vZGVsIGluIGFuIGVhc3kvdGlkeSB3YXkuICAgCgpUaGUgYHRpZHkoKWAgZnVuY3Rpb24gcmV0dXJucyBhIHRpZHkgZGF0YSBmcmFtZSB3aXRoIGNvZWZmaWNpZW50cyBmcm9tIHRoZSBtb2RlbCAob25lIHJvdyBwZXIgY29lZmZpY2llbnQpLgoKTWFueSBvdGhlciBgYnJvb21gIGZ1bmN0aW9ucyBjdXJyZW50bHkgb25seSB3b3JrIHdpdGggYHBhcnNuaXBgIG9iamVjdHMsIG5vdCByYXcgYHdvcmtmbG93c2Agb2JqZWN0cy4gCgpIb3dldmVyLCB3ZSBjYW4gdXNlIHRoZSBgdGlkeWAgZnVuY3Rpb24gaWYgd2UgZmlyc3QgdXNlIHRoZSBgcHVsbF93b3JrZmxvd19maXQoKWAgZnVuY3Rpb24uCgpgYGB7cn0Kd2Zsb3dvdXRwdXQgPC0gUE1fd2Zsb3dfZml0ICU+JSAKICBwdWxsX3dvcmtmbG93X2ZpdCgpICU+JSAKICBicm9vbTo6dGlkeSgpIApgYGAKCgpgYGB7cn0Kd2Zsb3dvdXRwdXQKYGBgCgpXZSBoYXZlIGZpdCBvdXIgbW9kZWwgb24gb3VyIHRyYWluaW5nIGRhdGEsIHdoaWNoIG1lYW5zIHdlIGhhdmUgY3JlYXRlZCBhIG1vZGVsIHRvIHByZWRpY3QgdmFsdWVzIG9mIGFpciBwb2xsdXRpb24gYmFzZWQgb24gdGhlIHByZWRpY3RvcnMgdGhhdCB3ZSBoYXZlIGluY2x1ZGVkLiBZYXkhCgpPbmUgbGFzdCB0aGluZyBiZWZvcmUgd2UgbGVhdmUgdGhpcyBzZWN0aW9uLiAKV2Ugb2Z0ZW4gYXJlIGludGVyZXN0ZWQgaW4gZ2V0dGluZyBhIHNlbnNlIG9mIHdoaWNoIHZhcmlhYmxlcyBhcmUgdGhlIG1vc3QgaW1wb3J0YW50IGluIG91ciBtb2RlbC4gCldlIGNhbiBleHBsb3JlIHRoZSB2YXJpYWJsZSBpbXBvcnRhbmNlIHVzaW5nIHRoZSBgdmlwKClgIGZ1bmN0aW9uIG9mIHRoZSBgdmlwYCBwYWNrYWdlLiAKVGhpcyBmdW5jdGlvbiBjcmVhdGVzIGEgYmFyIHBsb3Qgb2YgdmFyaWFibGUgaW1wb3J0YW5jZSBzY29yZXMgZm9yIGVhY2ggcHJlZGljdG9yIHZhcmlhYmxlIChvciBmZWF0dXJlKSBpbiBhIG1vZGVsLiAKVGhlIGJhciBwbG90IGlzIG9yZGVyZWQgYnkgaW1wb3J0YW5jZSAoaGlnaGVzdCB0byBzbWFsbGVzdCkuIAoKCk5vdGljZSBhZ2FpbiB0aGF0IHdlIG5lZWQgdG8gdXNlIHRoZSBgcHVsbF93b3JrZmxvd19maXQoKWAgZnVuY3Rpb24uCgpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgdG9wIDEwIGNvbnRyaWJ1dGluZyB2YXJpYWJsZXM6CgpgYGB7cn0KUE1fd2Zsb3dfZml0ICU+JSAKICBwdWxsX3dvcmtmbG93X2ZpdCgpICU+JSAKICB2aXAobnVtX2ZlYXR1cmVzID0gMTApCmBgYAoKVGhlIHN0YXRlIGluIHdoaWNoIHRoZSBtb25pdG9yIHdhcyBsb2NhdGVkIGFuZCB0aGUgQ01BUSBtb2RlbCBhbmQgdGhlIGFvZCBzYXRlbGxpdGUgaW5mb3JtYXRpb24gYXBwZWFyIHRvIGJlIHRoZSBtb3N0IGltcG9ydGFudCBmb3IgcHJlZGljdGluZyB0aGUgYWlyIHBvbGx1dGlvbiBhdCBhIGdpdmVuIG1vbml0b3IuCgojIyAqKk1vZGVsIHBlcmZvcm1hbmNlKioKKioqCgpJbiB0aGlzIG5leHQgc2VjdGlvbiwgb3VyIGdvYWwgaXMgdG8gYXNzZXNzIHRoZSBvdmVyYWxsIG1vZGVsIHBlcmZvcm1hbmNlLiAKVGhlIHdheSB3ZSBkbyB0aGlzIGlzIHRvIGNvbXBhcmUgdGhlIHNpbWlsYXJpdHkgYmV0d2VlbiB0aGUgcHJlZGljdGVkIGVzdGltYXRlcyBvZiB0aGUgb3V0Y29tZSB2YXJpYWJsZSBwcm9kdWNlZCBieSB0aGUgbW9kZWwgYW5kIHRoZSB0cnVlIG91dGNvbWUgdmFyaWFibGUgdmFsdWVzLiAKCklmIHlvdSByZWNhbGwgdGhlIFtXaGF0IGlzIG1hY2hpbmUgbGVhcm5pbmc/XSgjd2hhdGlzbWwpIHNlY3Rpb24sIHdlIHNob3dlZCBob3cgdG8gdGhpbmsgYWJvdXQgbWFjaGluZSBsZWFybmluZyAoTUwpIGFzIGFuIG9wdGltaXphdGlvbiBwcm9ibGVtIHRoYXQgdHJpZXMgdG8gbWluaW1pemUgdGhlIGRpc3RhbmNlIGJldHdlZW4gb3VyIHByZWRpY3RlZCBvdXRjb21lICRcaGF0e1l9ID0gZihYKSQgYW5kIGFjdHVhbCBvdXRjb21lICRZJCB1c2luZyBvdXIgZmVhdHVyZXMgKG9yIHByZWRpY3RvciB2YXJpYWJsZXMpICRYJCBhcyBpbnB1dCB0byBhIGZ1bmN0aW9uICRmJCB0aGF0IHdlIHdhbnQgdG8gZXN0aW1hdGUuIAoKJCRkKFkgLSBcaGF0e1l9KSQkCgpBcyBvdXIgZ29hbCBpbiB0aGlzIHNlY3Rpb24gaXMgdG8gYXNzZXNzIG92ZXJhbGwgbW9kZWwgcGVyZm9ybWFuY2UsIHdlIHdpbGwgbm93IHRhbGsgYWJvdXQgZGlmZmVyZW50IGRpc3RhbmNlIG1ldHJpY3MgdGhhdCB5b3UgY2FuIHVzZS4gCgpGaXJzdCwgbGV0J3MgcHVsbCBvdXQgb3VyIHByZWRpY3RlZCBvdXRjb21lIHZhbHVlcyAkXGhhdHtZfSA9IGYoWCkkIGZyb20gdGhlIG1vZGVscyB3ZSBmaXQgKHVzaW5nIGRpZmZlcmVudCBhcHByb2FjaGVzKS4gCgoKYGBge3J9CndmX2ZpdCA8LSBQTV93Zmxvd19maXQgJT4lIAogIHB1bGxfd29ya2Zsb3dfZml0KCkKCndmX2ZpdHRlZF92YWx1ZXMgPC0gZml0dGVkKHdmX2ZpdFtbImZpdCJdXSkKaGVhZCh3Zl9maXR0ZWRfdmFsdWVzKQpgYGAKCkFsdGVybmF0aXZlbHksIHdlIGNhbiBnZXQgdGhlIGZpdHRlZCB2YWx1ZXMgdXNpbmcgdGhlIGBhdWdtZW50KClgIGZ1bmN0aW9uIG9mIHRoZSBgYnJvb21gIHBhY2thZ2UgdXNpbmcgdGhlIG91dHB1dCBmcm9tIGB3b3JrZmxvd3NgOiAKCmBgYHtyfQp3Zl9maXR0ZWRfdmFsdWVzIDwtIAogIGJyb29tOjphdWdtZW50KHdmX2ZpdFtbImZpdCJdXSwgZGF0YSA9IGJha2VkX3RyYWluKSAlPiUgCiAgc2VsZWN0KHZhbHVlLCAuZml0dGVkOi5zdGQucmVzaWQpCgpoZWFkKHdmX2ZpdHRlZF92YWx1ZXMpCgpgYGAKCk5vdGUgdGhhdCBiZWN1YXNlIHdlIHVzZSB0aGUgYWN0dWFsIHdvcmtmbG93IGhlcmUsIHdlIGNhbiAoYW5kIGFjdHVhbGx5IG5lZWQgdG8pIHVzZSB0aGUgcmF3IGRhdGEgaW5zdGVhZCBvZiB0aGUgcHJlLXByb2Nlc3NlZCBkYXRhLgoKYGBge3J9CnZhbHVlc19wcmVkX3RyYWluIDwtIAogIHByZWRpY3QoUE1fd2Zsb3dfZml0LCB0cmFpbl9wbSkgJT4lIAogIGJpbmRfY29scyh0cmFpbl9wbSAlPiUgc2VsZWN0KHZhbHVlLCBmaXBzLCBjb3VudHksIGlkKSkgCgp2YWx1ZXNfcHJlZF90cmFpbgoKYGBgCgojIyMgKipWaXN1YWxpemluZyBtb2RlbCBwZXJmb3JtYW5jZSoqCioqKgoKTm93LCB3ZSBjYW4gY29tcGFyZSB0aGUgcHJlZGljdGVkIG91dGNvbWUgdmFsdWVzIChvciBmaXR0ZWQgdmFsdWVzKSAkXGhhdHtZfSQgdG8gdGhlIGFjdHVhbCBvdXRjb21lIHZhbHVlcyAkWSQgdGhhdCB3ZSBvYnNlcnZlZDogCgpgYGB7cn0Kd2ZfZml0dGVkX3ZhbHVlcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gIHZhbHVlLCB5ID0gLmZpdHRlZCkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgeGxhYigiYWN0dWFsIG91dGNvbWUgdmFsdWVzIikgKyAKICB5bGFiKCJwcmVkaWN0ZWQgb3V0Y29tZSB2YWx1ZXMiKQpgYGAKCk9LLCBzbyBvdXIgcmFuZ2Ugb2YgdGhlIHByZWRpY3RlZCBvdXRjb21lIHZhbHVlcyBhcHBlYXJzIHRvIGJlIHNtYWxsZXIgdGhhbiB0aGUgcmVhbCB2YWx1ZXMuIApXZSBjb3VsZCBwcm9iYWJseSBkbyBhIGJpdCBiZXR0ZXIuCgojIyMgKipRdWFudGlmeWluZyBtb2RlbCBwZXJmb3JtYW5jZSoqCioqKgoKTmV4dCwgbGV0J3MgdXNlIGRpZmZlcmVudCBkaXN0YW5jZSBmdW5jdGlvbnMgJGQoXGNkb3QpJCB0byBhc3Nlc3MgaG93IGZhciBvZmYgb3VyIHByZWRpY3RlZCBvdXRjb21lICRcaGF0e1l9ID0gZihYKSQgYW5kIGFjdHVhbCBvdXRjb21lICRZJCB2YWx1ZXMgYXJlIGZyb20gZWFjaCBvdGhlcjogCgokJGQoWSAtIFxoYXR7WX0pJCQKCkFzIG1lbnRpb25lZCwgdGhlcmUgYXJlIGVudGlyZSBzY2hvbGFybHkgZmllbGRzIG9mIHJlc2VhcmNoIGRlZGljYXRlZCB0byBpZGVudGlmeWluZyBkaWZmZXJlbnQgZGlzdGFuY2UgbWV0cmljcyAkZChcY2RvdCkkIGZvciBtYWNoaW5lIGxlYXJuaW5nIGFwcGxpY2F0aW9ucy4gCkhvd2V2ZXIsIHdoZW4gcGVyZm9ybWluZyBwcmVkaWN0aW9uIHdpdGggYSBjb250aW51b3VzIG91dGNvbWUgJFkkLCBhIGZldyBvZiB0aGUgbW9zdGx5IGNvbW1vbmx5IHVzZWQgZGlzdGFuY2UgbWV0cmljcyBhcmU6IAoKMS4gbWVhbiBhYnNvbHV0ZSBlcnJvciAoYG1hZWApICAKCiQkTUFFID0gXGZyYWN7XHN1bV97aT0xfV57bn17KHxcaGF0e3lfdH0tIHlfdHwpfV4yfXtufSQkCgoKMi4gUiBzcXVhcmVkIGVycm9yIChgcnNxYCkgLS0gdGhpcyBpcyBhbHNvIGtub3duIGFzIHRoZSBjb2VmZmljaWVudCBvZiBkZXRlcm1pbmF0aW9uIHdoaWNoIGlzIHRoZSBzcXVhcmVkIGNvcnJlbGF0aW9uIGJldHdlZW4gdHJ1dGggYW5kIGVzdGltYXRlCgpUaGlzIGlzIGNhbGN1bGF0ZWQgYW5kIDEgbWludXMgdGhlIGZyYWN0aW9uIG9mIHRoZSByZXNpZHVhbCBzdW0gb2Ygc3F1YXJlcyAoJFNTX3JlcyQpIGJ5IHRoZSB0b3RhbCBzdW0gb2Ygc3F1YXJlcyAoJFNTX3RvdCQpCgoKJCRSU1EgPSBSXjIgPSAxIC0gXGZyYWN7U1NyZXN9e1NTdG90fSQkCgokJFNTX3t0b3R9ID0gXHN1bV97aT0xfV57bn17KHlfaS0gXGJhcnt5fSl9XjIkJApUaGUgdG90YWwgc3VtIG9mIHNxdWFyZXMgaXMgcHJvcG9ydGlvbmFsIHRvIHRoZSB2YXJpYW5jZSBvZiB0aGUgZGF0YS4gSXQgaXMgY2FsY3VsYXRlZCBhcyB0aGUgc3VtIG9mIGVhY2ggIHRydWUgdmFsdWUgZnJvbSB0aGUgbWVhbiB0cnVlIHZhbHVlICgkXGJhcnt5fSQpLgoKJCRTU197cmVzfSA9IFxzdW1fe2k9MX1ee259eyh5X2ktIFxoYXR7eV9pfSl9XjIkJAoKVGhlIHN1bSBvZiBzcXVhcmVzIG9mIHJlc2lkdWFscyBpcyBjYWxjdWxhdGVkIGFzIHRoZSBzdW0gb2YgZWFjaCBwcmVkaWN0ZWQgdmFsdWUgKCRcaGF0e3lfaX0kIG9yIHNvbWV0aW1lcyAkZl9pJCkgZnJvbSB0aGUgdHJ1ZSB2YWx1ZSAoJHlfaSQpLiAKCgozLiBbcm9vdCBtZWFuIHNxdWFyZWQgZXJyb3JdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1Jvb3QtbWVhbi1zcXVhcmVfZGV2aWF0aW9uKXt0YXJnZXQ9Il9ibGFuayJ9IChgcm1zZWApICAgCgokJFJNU0UgPSBcc3FydHtcZnJhY3tcc3VtX3tpPTF9XntufXsoXGhhdHt5X3R9LSB5X3QpfV4yfXtufX0kJAoKCgoKT25lIHdheSB0byBjYWxjdWxhdGUgdGhlc2UgbWV0cmljcyB3aXRoaW4gdGhlIGB0aWR5bW9kZWxzYCBmcmFtZXdvcmsgaXMgdG8gdXNlIHRoZSBgeWFyZHN0aWNrYCBwYWNrYWdlIHVzaW5nIHRoZSBgbWV0cmljcygpYCBmdW5jdGlvbi4gCgpgYGB7cn0KeWFyZHN0aWNrOjptZXRyaWNzKHdmX2ZpdHRlZF92YWx1ZXMsIAogICAgICAgICAgICAgICAgICAgdHJ1dGggPSB2YWx1ZSwgZXN0aW1hdGUgPSAuZml0dGVkKQpgYGAKCkFsdGVybmF0aXZlbHkgaWYgeW91IG9ubHkgd2FudGVkIG9uZSBtZXRyaWMgeW91IGNvdWxkIHVzZSB0aGUgYG1hZSgpYCwgYHJzcSgpYCwgb3IgYHJtc2UoKWAgZnVuY3Rpb25zLCByZXNwZWN0aXZlbHkuIAoKYGBge3J9CnlhcmRzdGljazo6bWFlKHdmX2ZpdHRlZF92YWx1ZXMsIAogICAgICAgICAgICAgICB0cnV0aCA9IHZhbHVlLCBlc3RpbWF0ZSA9IC5maXR0ZWQpCmBgYAoKIyMgKipDcm9zcyB2YWxpZGF0aW9uKioKKioqCgpVbnRpbCBub3cgd2UgaGF2ZSB1c2VkIGV2ZXJ5dGhpbmcgaW4gb3VyICJ0cmFpbmluZyIgZGF0YXNldCAoYW5kIGhhdmUgbm90IHRvdWNoZWQgdGhlICJ0ZXN0aW5nIiBkYXRhc2V0KSBmcm9tIHRoZSBgcnNhbXBsZWAgcGFja2FnZSB0byBidWlsZCBvdXIgbWFjaGluZSBsZWFybmluZyAoTUwpIG1vZGVsICRcaGF0e1l9ID0gZihYKSQgKG9yIHRvIGVzdGltYXRlICRmJCB1c2luZyB0aGUgZmVhdHVyZXMgb3IgcHJlZGljdG9yIHZhcmlhYmxlICRYJCkuIAoKSGVyZSwgd2UgdGFrZSBtb3ZlIHRoaXMgYmV5b25kIHRoZSBzaW1wbGUgc3BsaXQgaW50byB0cmFpbmluZyBhbmQgdGVzdGluZyBkYXRhIHNldHMuIApXZSB3aWxsIGFnYWluIHVzZSB0aGUgYHJzYW1wbGVgIHBhY2thZ2UgYWdhaW4gaW4gb3JkZXIgdG8gZnVydGhlciBpbXBsZW1lbnQgd2hhdCBhcmUgY2FsbGVkIFtjcm9zcyB2YWxpZGF0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Dcm9zcy12YWxpZGF0aW9uXyhzdGF0aXN0aWNzKSl7dGFyZ2V0PSJfYmxhbmsifSB0ZWNobmlxdWVzLiBUaGlzIGlzIGFsc28gY2FsbGVkICoqcmUtc2FtcGxpbmcqKiBvciAqKnJlcGFydGlvbmluZyoqLiAgCgoqKk5vdGUqKjogd2UgYXJlIG5vdCBhY3R1YWxseSBnZXR0aW5nIG5ldyBzYW1wbGVzIGZyb20gdGhlIHVuZGVybHlpbmcgZGlzdHJpYnV0aW9uIHNvIHRoZSB0ZXJtIHJlLXNhbXBsaW5nIGlzIGEgYml0IG9mIGEgbWlzbm9tZXIuCgpbQ3Jvc3MgdmFsaWRhdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ3Jvc3MtdmFsaWRhdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gc3BsaXRzIG91ciB0cmFpbmluZyBkYXRhIGludG8gbXVsdGlwbGUgdHJhaW5pbmcgZGF0YSBzZXRzIHRvIGFsbG93IGZvciBhIGRlZXBlciBhc3Nlc3NtZW50IG9mIHRoZSBhY2N1cmFjeSBvZiB0aGUgbW9kZWwuCgpIZXJlIGlzIGEgdmlzdWFsaXphdGlvbiBvZiB0aGUgY29uY2VwdCBmb3IgY3Jvc3MgdmFsaWRhdGlvbi9yZXNhbXBsaW5nL3JlcGFydGl0aW9uaW5nIGZyb20gW01heCBLdWhuXShodHRwczovL3Jlc291cmNlcy5yc3R1ZGlvLmNvbS9hdXRob3JzL21heC1rdWhuKXt0YXJnZXQ9Il9ibGFuayJ9OgoKYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iODAwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCJyZXNhbXBsaW5nLnBuZyIpKQpgYGAKClRlY2huaWNhbGx5IGNyZWF0aW5nIG91ciB0ZXN0aW5nIGFuZCB0cmFpbmluZyBzZXQgb3V0IG9mIG91ciBvcmlnaW5hbCB0cmFpbmluZyBkYXRhIGlzIHNvbWV0aW1lcyBjb25zaWRlcmVkIGEgZm9ybSBvZiBbY3Jvc3MgdmFsaWRhdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ3Jvc3MtdmFsaWRhdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0sIGNhbGxlZCB0aGUgaG9sZG91dCBtZXRob2QuIApUaGUgcmVhc29uIHdlIGRvIHRoaXMgaXQgc28gd2UgY2FuIGdldCBhIGJldHRlciBzZW5zZSBvZiB0aGUgYWNjdXJhY3kgb2Ygb3VyIG1vZGVsIHVzaW5nIGRhdGEgdGhhdCB3ZSBkaWQgbm90IHRyYWluIGl0IG9uLiAKCkhvd2V2ZXIsIHdlIGNhbiBhY3R1YWxseSBkbyBhIGJldHRlciBqb2Igb2Ygb3B0aW1pemluZyBvdXIgbW9kZWwgZm9yIGFjY3VyYWN5IGlmIHdlIGFsc28gcGVyZm9ybSBhbm90aGVyIHR5cGUgb2YgW2Nyb3NzIHZhbGlkYXRpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Nyb3NzLXZhbGlkYXRpb25fKHN0YXRpc3RpY3MpKXt0YXJnZXQ9Il9ibGFuayJ9IG9uIHRoZSBuZXdseSBkZWZpbmVkIHRyYWluaW5nIHNldCB0aGF0IHdlIGp1c3QgY3JlYXRlZC4gClRoZXJlIGFyZSBtYW55IFtjcm9zcyB2YWxpZGF0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Dcm9zcy12YWxpZGF0aW9uXyhzdGF0aXN0aWNzKSl7dGFyZ2V0PSJfYmxhbmsifSBtZXRob2RzIGFuZCBtb3N0IGNhbiBiZSBlYXNpbHkgaW1wbGVtZW50ZWQgdXNpbmcgYHJzYW1wbGVgIHBhY2thZ2UuIApIZXJlLCB3ZSB3aWxsIHVzZSBhIHZlcnkgcG9wdWxhciBtZXRob2QgY2FsbGVkIGVpdGhlciBbay1mb2xkIG9yIHYtZm9sZCBjcm9zcyB2YWxpZGF0aW9uXShodHRwczovL21hY2hpbmVsZWFybmluZ21hc3RlcnkuY29tL2stZm9sZC1jcm9zcy12YWxpZGF0aW9uLyl7dGFyZ2V0PSJfYmxhbmsifS4gCgpUaGlzIG1ldGhvZCBpbnZvbHZlcyBlc3NlbnRpYWxseSBwcmVmb3JtaW5nIHRoZSBob2xkIG91dCBtZXRob2QgaXRlcmF0aXZlbHkgd2l0aCB0aGUgdHJhaW5pbmcgZGF0YS4gCgpGaXJzdCwgdGhlIHRyYWluaW5nIHNldCBpcyBkaXZpZGVkIGludG8gJHYkIChvciBvZnRlbiBjYWxsZWQgY2FsbGVkICRrJCkgZXF1YWxseSBzaXplZCBzbWFsbGVyIHBpZWNlcy4gCgpOZXh0LCB0aGUgbW9kZWwgaXMgdHJhaW5lZCBvbiB0aGUgbW9kZWwgb24gJHYkLTEgc3Vic2V0cyBvZiB0aGUgZGF0YSBpdGVyYXRpdmVseSAocmVtb3ZpbmcgYSBkaWZmZXJlbnQgJHYkIHVudGlsIGFsbCBwb3NzaWJsZSAkdiQtMSBzZXRzIGhhdmUgYmVlbiBldmFsdWF0ZWQpIHRvIGdldCBhIHNlbnNlIG9mIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGUgbW9kZWwuIApUaGlzIGlzIHJlYWxseSB1c2VmdWwgZm9yIGZpbmUgdHVuaW5nIHNwZWNpZmljIGFzcGVjdHMgb2YgdGhlIG1vZGVsIGluIGEgcHJvY2VzcyBjYWxsZWQgbW9kZWwgdHVuaW5nLCB3aGljaCB3ZSB3aWxsIGxlYXJuIGFib3V0IGluIHRoZSBuZXh0IHNlY3Rpb24uIAoKSGVyZSBpcyBhIHZpc3VhbGl6YXRpb24gb2YgaG93IHRoZSBmb2xkcyBhcmUgY3JlYXRlZDoKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwgInZmb2xkLnBuZyIpKQpgYGAKCioqTm90ZSoqOiBQZW9wbGUgdHlwaWNhbGx5IGlnbm9yZSBzcGF0aWFsIGRlcGVuZGVuY2Ugd2l0aCBjcm9zcyB2YWxpZGF0aW9uIG9mIGFpciBwb2xsdXRpb24gbW9uaXRvcmluZyBkYXRhIGluIHRoZSBhaXIgcG9sbHV0aW9uIGZpZWxkLCBzbyB3ZSB3aWxsIGRvIHRoZSBzYW1lLiAgSG93ZXZlciwgaXQgbWlnaHQgbWFrZSBzZW5zZSB0byBsZWF2ZSBvdXQgYmxvY2tzIG9mIG1vbml0b3JzIHJhdGhlciB0aGFuICByYW5kb20gaW5kaXZpZHVhbCBtb25pdG9ycyB0byBoZWxwIGFjY291bnQgZm9yIHNvbWUgc3BhdGlhbCBkZXBlbmRlbmNlLgoKIyMjICoqQ3JlYXRpbmcgdGhlICR2JC1mb2xkcyB1c2luZyBgcnNhbXBsZWAqKgoqKioKClRoZSBbYHZmb2xkX2N2KClgXShodHRwczovL3RpZHltb2RlbHMuZ2l0aHViLmlvL3JzYW1wbGUvcmVmZXJlbmNlL3Zmb2xkX2N2Lmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gZnVuY3Rpb24gb2YgdGhlIGByc2FtcGxlYCBwYWNrYWdlIGNhbiBiZSB1c2VkIHRvIHBhcnNlIHRoZSB0cmFpbmluZyBkYXRhIGludG8gZm9sZHMgZm9yICR2JC1mb2xkIGNyb3NzIHZhbGlkYXRpb24uCgotIFRoZSBgdmAgYXJndW1lbnQgc3BlY2lmaWVzIHRoZSBudW1iZXIgb2YgZm9sZHMgdG8gY3JlYXRlLgotIFRoZSBgcmVwZWF0c2AgYXJndW1lbnQgc3BlY2lmaWVzIGlmIGFueSBzYW1wbGVzIHNob3VsZCBiZSByZXBlYXRlZCBhY3Jvc3MgZm9sZHMgLSBkZWZhdWx0IGlzIGBGQUxTRWAKLSBUaGUgYHN0cmF0YWAgYXJndW1lbnQgc3BlY2lmaWVzIGEgdmFyaWFibGUgdG8gc3RyYXRpZnkgc2FtcGxlcyBhY3Jvc3MgZm9sZHMgLSBqdXN0IGxpa2UgaW4gYGluaXRpYWxfc3BsaXQoKWAuCgpBZ2FpbiwgYmVjYXVzZSB0aGVzZSBhcmUgY3JlYXRlZCBhdCByYW5kb20sIHdlIG5lZWQgdG8gdXNlIHRoZSBiYXNlIGBzZXQuc2VlZCgpYCBmdW5jdGlvbiBpbiBvcmRlciB0byBvYnRhaW4gdGhlIHNhbWUgcmVzdWx0cyBlYWNoIHRpbWUgd2Uga25pdCB0aGlzIGRvY3VtZW50LiAKR2VuZXJhbGx5IHNwZWFraW5nIHVzaW5nIDEwIGZvbGRzIGlzIGdvb2QgcHJhY3RpY2UsIGJ1dCB0aGlzIGRlcGVuZHMgb24gdGhlIHZhcmlhYmlsaXR5IHdpdGhpbiB5b3VyIGRhdGEuIApXZSBhcmUgZ29pbmcgdG8gdXNlIDQgZm9yIHRoZSBzYWtlIG9mIGV4cGVkaWVuY3kuIAoKYGBge3J9CnNldC5zZWVkKDEyMzQpCnZmb2xkX3BtIDwtIHJzYW1wbGU6OnZmb2xkX2N2KGRhdGEgPSB0cmFpbl9wbSwgdiA9IDQpCnZmb2xkX3BtCnB1bGwodmZvbGRfcG0sIHNwbGl0cykKYGBgCgpOb3cgd2UgY2FuIHNlZSB0aGF0IHdlIGhhdmUgY3JlYXRlZCA0IGZvbGRzIG9mIHRoZSBkYXRhIGFuZCB3ZSBjYW4gc2VlIGhvdyBtYW55IHZhbHVlcyB3ZXJlIHNldCBhc2lkZSBmb3IgdGVzdGluZyAoY2FsbGVkIGFzc2Vzc2luZyBmb3IgY3Jvc3MgdmFsaWRhdGlvbiBzZXRzKSBhbmQgdHJhaW5pbmcgKGNhbGxlZCBhbmFseXNpcyBmb3IgY3Jvc3MgdmFsaWRhdGlvbiBzZXRzKSB3aXRoaW4gZWFjaCBmb2xkLgoKT25jZSB0aGUgZm9sZHMgYXJlIGNyZWF0ZWQgdGhleSBjYW4gYmUgdXNlZCB0byBldmFsdWF0ZSBwZXJmb3JtYW5jZSBieSBmaXR0aW5nIHRoZSBtb2RlbCB0byBlYWNoIG9mIHRoZSByZS1zYW1wbGVzIHRoYXQgd2UgY3JlYXRlZDoKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwgImNyb3NzX3ZhbGlkYXRpb24ucG5nIikpCmBgYAoKIyMjICoqQXNzZXNzaW5nIG1vZGVsIHBlcmZvcm1hbmNlIG9uICR2JC1mb2xkcyB1c2luZyBgdHVuZWAqKgoqKioKCldlIGNhbiBmaXQgdGhlIG1vZGVsIHRvIG91ciBjcm9zcyB2YWxpZGF0aW9uIGZvbGRzIHVzaW5nIHRoZSBgZml0X3Jlc2FtcGxlcygpYCBmdW5jdGlvbiBvZiB0aGUgYHR1bmVgIHBhY2thZ2UsIGJ5IHNwZWNpZnlpbmcgb3VyIGB3b3JrZmxvd2Agb2JqZWN0IGFuZCB0aGUgY3Jvc3MgdmFsaWRhdGlvbiBmb2xkIG9iamVjdCB3ZSBqdXN0IGNyZWF0ZWQuIApTZWUgW2hlcmVdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vdHVuZS9yZWZlcmVuY2UvZml0X3Jlc2FtcGxlcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9IGZvciBtb3JlIGluZm9ybWF0aW9uLgoKCmBgYHtyfQpyZXNhbXBsZV9maXQgPC0gdHVuZTo6Zml0X3Jlc2FtcGxlcyhQTV93ZmxvdywgdmZvbGRfcG0pCmBgYAoKV2UgY2FuIG5vdyB0YWtlIGEgbG9vayBhdCB2YXJpb3VzIHBlcmZvcm1hbmNlIG1ldHJpY3MgYmFzZWQgb24gdGhlIGZpdCBvZiBvdXIgY3Jvc3MgdmFsaWRhdGlvbiAicmVzYW1wbGVzIi4gClRvIGRvIHRoaXMgd2Ugd2lsbCB1c2UgdGhlIGBzaG93X2Jlc3QoKWAgZnVuY3Rpb24gb2YgdGhlIGB0dW5lYCBwYWNrYWdlLgoKYGBge3J9CnR1bmU6OnNob3dfYmVzdChyZXNhbXBsZV9maXQsIG1ldHJpYyA9ICJybXNlIikKYGBgCgpIZXJlIHdlIGNhbiBzZWUgdGhlIG1lYW4gYFJNU0VgIHZhbHVlIGFjcm9zcyBhbGwgZm91ciBmb2xkcy4gVGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBgc2hvd19iZXN0KClgIGJlY2F1c2UgaXQgaXMgYWxzbyB1c2VkIGZvciBtb2RlbCB0dW5pbmcgYW5kIGl0IHdpbGwgc2hvdyB0aGUgcGFyYW1ldGVyIGNvbWJpbmF0aW9uIHdpdGggdGhlIGJlc3QgcGVyZm9ybWFuY2UsIHdlIHdpbGwgZGlzY3VzcyB0aGlzIG1vcmUgbGF0ZXIgaW4gdGhlIGNhc2Ugc3R1ZHkuCgoKIyAqKkRhdGEgQW5hbHlzaXMqKgoqKioKCkluIHRoZSBwcmV2aW91cyBzZWN0aW9uLCB3ZSBkZW1vbnN0cmF0ZWQgaG93IHRvIGJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBtb2RlbCAoc3BlY2lmaWNhbGx5IGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwpIHRvIHByZWRpY3QgYWlyIHBvbGx1dGlvbiB3aXRoIHRoZSBgdGlkeW1vZGVsc2AgZnJhbWV3b3JrLiAKCkluIHRoZSBuZXh0IGZldyBzZWN0aW9uLCB3ZSB3aWxsIGRlbW9uc3RyYXRlIGFub3RoZXIgbWFjaGluZSBsZWFybmluZyBtb2RlbC4gCgoKIyMgKipSYW5kb20gRm9yZXN0KioKKioqCgpOb3csIHdlIGFyZSBnb2luZyB0byBwcmVkaWN0IG91ciBvdXRjb21lIHZhcmlhYmxlIChhaXIgcG9sbHV0aW9uKSB1c2luZyBhIGRlY2lzaW9uIHRyZWUgbWV0aG9kIGNhbGxlZCBbcmFuZG9tIGZvcmVzdF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUmFuZG9tX2ZvcmVzdCl7dGFyZ2V0PSJfYmxhbmsifS4KCkEgW2RlY2lzaW9uIHRyZWVdKGh0dHBzOi8vbWVkaXVtLmNvbS9ncmV5YXRvbS9kZWNpc2lvbi10cmVlcy1hLXNpbXBsZS13YXktdG8tdmlzdWFsaXplLWEtZGVjaXNpb24tZGM1MDZhNDAzYWViKXt0YXJnZXQ9Il9ibGFuayJ9IGlzIGEgdG9vbCB0byBwYXJ0aXRpb24gZGF0YSBvciBhbnl0aGluZyByZWFsbHksIGJhc2VkIG9uIGEgc2VyaWVzIG9mIHNlcXVlbnRpYWwgKG9mdGVuIGJpbmFyeSkgZGVjaXNpb25zLCB3aGVyZSB0aGUgZGVjaXNpb25zIGFyZSBjaG9zZW4gYmFzZWQgb24gdGhlaXIgYWJpbGl0eSB0byBvcHRpbWFsbHkgc3BsaXQgdGhlIGRhdGEuCgpIZXJlIHlvdSBjYW4gc2VlIGEgc2ltcGxlIGV4YW1wbGU6CgpgYGB7ciwgZWNobyA9IEZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9taXJvLm1lZGl1bS5jb20vbWF4LzEwMDAvMSpMTW9KbVhDc1FsY2lHVEV5b1NOMzlnLmpwZWciKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3VuZGVyc3RhbmRpbmctcmFuZG9tLWZvcmVzdC01ODM4MWUwNjAyZDIpe3RhcmdldD0iX2JsYW5rIn0KCkluIHRoZSBjYXNlIG9mIFtyYW5kb20gZm9yZXN0XShodHRwczovL3Rvd2FyZHNkYXRhc2NpZW5jZS5jb20vZGVjaXNpb24tdHJlZS1lbnNlbWJsZXMtYmFnZ2luZy1hbmQtYm9vc3RpbmctMjY2YThiYTYwZmQ5KXt0YXJnZXQ9Il9ibGFuayJ9LCBtdWx0aXBsZSBkZWNpc2lvbiB0cmVlcyBhcmUgY3JlYXRlZCAtIGhlbmNlIHRoZSBuYW1lIGZvcmVzdCwgYW5kIGVhY2ggdHJlZSBpcyBidWlsdCB1c2luZyBhIHJhbmRvbSBzdWJzZXQgb2YgdGhlIHRyYWluaW5nIGRhdGEgKHdpdGggcmVwbGFjZW1lbnQpIC0gaGVuY2UgdGhlIGZ1bGwgbmFtZSByYW5kb20gZm9yZXN0LiBUaGlzIHJhbmRvbSBhc3BlY3QgaGVscHMgdG8ga2VlcCB0aGUgYWxnb3JpdGhtIGZyb20gb3ZlcmZpdHRpbmcgdGhlIGRhdGEuCgpUaGUgbWVhbiBvZiB0aGUgcHJlZGljdGlvbnMgZnJvbSBlYWNoIG9mIHRoZSB0cmVlcyBpcyB1c2VkIGluIHRoZSBmaW5hbCBvdXRwdXQuCgpgYGB7ciwgZWNobyA9IEZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9taXJvLm1lZGl1bS5jb20vbWF4LzE0MDAvMCpmX3FRUEZwZG9mV0dMUXFjLnBuZyIpCmBgYAoKCkluIG91ciBjYXNlLCB3ZSBhcmUgZ29pbmcgdG8gdXNlIHRoZSByYW5kb20gZm9yZXN0IG1ldGhvZCBvZiB0aGUgdGhlIGByYW5kb21Gb3Jlc3RgIHBhY2thZ2UuIAoKVGhpcyBwYWNrYWdlIGlzIGN1cnJlbnRseSBub3QgY29tcGF0aWJsZSB3aXRoIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB0aGF0IGhhdmUgbW9yZSB0aGFuIDUzIGxldmVscy4gU2VlIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmFuZG9tRm9yZXN0L05FV1MpIGZvciB0aGUgZG9jdW1lbnRhdGlvbiBhYm91dCB3aGVuIHRoaXMgd2FzIHVwZGF0ZWQgZnJvbSAyNSBsZXZlbHMuIFRodXMgd2Ugd2lsbCByZW1vdmUgdGhlIGB6Y3RhYCAgYW5kIGBjb3VudHlgIHZhcmlhYmxlcy4KCk5vdGUgdGhhdCB0aGUgYHN0ZXBfbm92ZWwoKWAgZnVuY3Rpb24gaXMgbmVjZXNzYXJ5IGhlcmUgZm9yIHRoZSBgc3RhdGVgIHZhcmlhYmxlIHRvIGdldCBhbGwgY3Jvc3MgdmFsaWRhdGlvbiBmb2xkcyB0byB3b3JrLCBiZWNhdXNlIHRoZXJlIHdpbGwgYmUgZGlmZmVyZW50IGxldmVscyBpbmNsdWRlZCBpbiBlYWNoIGZvbGQgdGVzdCBhbmQgdHJhaW5pbmcgc2V0cy4gVGhlIG5ldyBsZXZlbHMgZm9yIHNvbWUgb2YgdGhlIHRlc3Qgc2V0cyB3b3VsZCBvdGhlcndpc2UgcmVzdWx0IGluIGFuIGVycm9yLgoKQWNjb3JkaW5nIHRvIHRoZSBbZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3JlY2lwZXMvdmVyc2lvbnMvMC4xLjEzL3RvcGljcy9zdGVwX25vdmVsKSBmb3IgdGhlIGByZWNpcGVzYCBwYWNrYWdlOgoKPiBzdGVwX25vdmVsIGNyZWF0ZXMgYSBzcGVjaWZpY2F0aW9uIG9mIGEgcmVjaXBlIHN0ZXAgdGhhdCB3aWxsIGFzc2lnbiBhIHByZXZpb3VzbHkgdW5zZWVuIGZhY3RvciBsZXZlbCB0byBhIG5ldyB2YWx1ZS4KCmBgYHtyfQpSRl9yZWMgPC0gcmVjaXBlKHRyYWluX3BtKSAlPiUKICAgIHVwZGF0ZV9yb2xlKGV2ZXJ5dGhpbmcoKSwgbmV3X3JvbGUgPSAicHJlZGljdG9yIiklPiUKICAgIHVwZGF0ZV9yb2xlKHZhbHVlLCBuZXdfcm9sZSA9ICJvdXRjb21lIiklPiUKICAgIHVwZGF0ZV9yb2xlKGlkLCBuZXdfcm9sZSA9ICJpZCB2YXJpYWJsZSIpICU+JQogICAgdXBkYXRlX3JvbGUoImZpcHMiLCBuZXdfcm9sZSA9ICJjb3VudHkgaWQiKSAlPiUKICAgIHN0ZXBfbm92ZWwoInN0YXRlIikgJT4lCiAgICBzdGVwX3N0cmluZzJmYWN0b3IoInN0YXRlIiwgImNvdW50eSIsICJjaXR5IikgJT4lCiAgICBzdGVwX3JtKCJjb3VudHkiKSAlPiUKICAgIHN0ZXBfcm0oInpjdGEiKSAlPiUKICAgIHN0ZXBfY29ycihhbGxfbnVtZXJpYygpKSU+JQogICAgc3RlcF9uenYoYWxsX251bWVyaWMoKSkKYGBgCgpUaGUgYHJhbmRfZm9yZXN0KClgIGZ1bmN0aW9uIG9mIHRoZSBgcGFyc25pcGAgcGFja2FnZSBoYXMgdGhyZWUgaW1wb3J0YW50IGFyZ3VtZW50cyB0aGF0IGFjdCBhcyBhbiBpbnRlcmZhY2UgZm9yIHRoZSBkaWZmZXJlbnQgcG9zc2libGUgZW5naW5lcyB0byBwZXJmb3JtIGEgcmFuZG9tIGZvcmVzdCBhbmFseXNpczoKCjEuIGBtdHJ5YCAtIFRoZSBudW1iZXIgb2YgcHJlZGljdG9yIHZhcmlhYmxlcyAob3IgZmVhdHVyZXMpIHRoYXQgd2lsbCBiZSByYW5kb21seSBzYW1wbGVkIGF0IGVhY2ggc3BsaXQgd2hlbiBjcmVhdGluZyB0aGUgdHJlZSBtb2RlbHMuIFRoZSBkZWZhdWx0IG51bWJlciBmb3IgcmVncmVzc2lvbiBhbmFseXNlcyBpcyB0aGUgbnVtYmVyIG9mIHByZWRpY3RvcnMgZGl2aWRlZCBieSAzLiAKMi4gYG1pbl9uYCAtIFRoZSBtaW5pbXVtIG51bWJlciBvZiBkYXRhIHBvaW50cyBpbiBhIG5vZGUgdGhhdCBhcmUgcmVxdWlyZWQgZm9yIHRoZSBub2RlIHRvIGJlIHNwbGl0IGZ1cnRoZXIuCjMuIGB0cmVlc2AgLSB0aGUgbnVtYmVyIG9mIHRyZWVzIGluIHRoZSBlbnNlbWJsZQoKV2Ugd2lsbCBzdGFydCBieSB0cnlpbmcgYW4gYG10cnlgIHZhbHVlIG9mIDEwIGFuZCBhIGBtaW5fbmAgdmFsdWUgb2YgMy4KCk5vdyB0aGF0IHdlIGhhdmUgb3VyIHJlY2lwZSAoYFJGX3JlY2ApLCBsZXQncyBzcGVjaWZ5IHRoZSBtb2RlbCB3aXRoIGByYW5kX2ZvcmVzdCgpYCBmcm9tIGBwYXJzbmlwYC4KCmBgYHtyfQpQTXRyZWVfbW9kZWwgPC0gCiAgcGFyc25pcDo6cmFuZF9mb3Jlc3QobXRyeSA9IDEwLCBtaW5fbiA9IDMpClBNdHJlZV9tb2RlbApgYGAKCk5leHQsIHdlIHNldCB0aGUgZW5naW5lIGFuZCBtb2RlOgoKTm90ZSB0aGF0IHlvdSBjb3VsZCBhbHNvIHVzZSB0aGUgYHJhbmdlcmAgb3IgYHNwYXJrYCBwYWNrYWdlcyBpbnN0ZWFkIG9mIGByYW5kb21Gb3Jlc3RgLgpJZiB5b3Ugd2VyZSB0byB1c2UgdGhlIGByYW5nZXJgIHBhY2thZ2UgdG8gaW1wbGVtZW50IHRoZSByYW5kb20gZm9yZXN0IGFuYWx5c2lzIHlvdSB3b3VsZCBuZWVkIHRvIHNwZWNpZnkgYW4gYGltcG9ydGFuY2VgIGFyZ3VtZW50IHRvIGJlIGFibGUgdG8gZXZhbHVhdGUgcHJlZGljdG9yIGltcG9ydGFuY2UuICBUaGUgb3B0aW9ucyBhcmUgYGltcHVyaXR5YCBvciBgcGVybXV0YXRpb25gLgoKVGhlc2Ugb3RoZXIgcGFja2FnZXMgaGF2ZSBkaWZmZXJlbnQgYWR2YW50YWdlcyBhbmQgZGlzYWR2YW50YWdlcy0gZm9yIGV4YW1wbGUgYHJhbmdlcmAgYW5kIGBzcGFya2AgYXJlIG5vdCBhcyBsaW1pdGluZyBmb3IgdGhlIG51bWJlciBvZiBjYXRlZ29yaWVzIGZvciBjYXRlZ29yaWNhbCB2YXJpYWJsZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZSB0aGVpciBkb2N1bWVudGF0aW9uOiBbaGVyZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3Jhbmdlci9yYW5nZXIucGRmKSBmb3IgcmFuZ2VyLCBbaGVyZV0oaHR0cDovL3NwYXJrLmFwYWNoZS5vcmcvZG9jcy9sYXRlc3QvbWxsaWItZW5zZW1ibGVzLmh0bWwjcmFuZG9tLWZvcmVzdHMpIGZvciBgc3BhcmtgLCBhbmQgW2hlcmVdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yYW5kb21Gb3Jlc3QvcmFuZG9tRm9yZXN0LnBkZikgZm9yIGByYW5kb21Gb3Jlc3RgLgoKU2VlIFtoZXJlXShodHRwczovL3BhcnNuaXAudGlkeW1vZGVscy5vcmcvcmVmZXJlbmNlL3JhbmRfZm9yZXN0Lmh0bWwpIGZvciBtb3JlIGRvY3VtZW50YXRpb24gYWJvdXQgaW1wbGVtZW50aW5nIHRoZXNlIGVuZ2luZSBvcHRpb25zIHdpdGggdGlkeW1vZGVscy4gTm90ZSB0aGF0IHRoZXJlIGFyZSBhbHNvIFtvdGhlcl0oaHR0cHM6Ly93d3cubGlua2VkaW4uY29tL3B1bHNlL2RpZmZlcmVudC1yYW5kb20tZm9yZXN0LXBhY2thZ2VzLXItbWFkaHVyLW1vZGkvKSBSIHBhY2thZ2VzIGZvciBpbXBsZW1lbnRpbmcgcmFuZG9tIGZvcmVzdCBhbGdvcml0aG1zLCBidXQgdGhlc2UgdGhyZWUgcGFja2FnZXMgKGByYW5nZXJgLCBgc3BhcmtgLCBhbmQgYHJhbmRvbUZvcmVzdGApIGFyZSBjdXJyZW50bHkgY29tcGF0aWJsZSB3aXRoIGB0aWR5bW9kZWxzYC4KCldlIGFsc28gbmVlZCB0byBzcGVjaWZ5IHdpdGggdGhlIGBzZXRfbW9kZSgpYCBmdW5jdGlvbiB0aGF0IG91ciBvdXRjb21lIHZhcmlhYmxlIChhaXIgcG9sbHV0aW9uKSBpcyBjb250aW51b3VzLiAKCmBgYHtyfQoKUkZfUE1fbW9kZWwgPC0gCiAgUE10cmVlX21vZGVsICU+JQogIHNldF9lbmdpbmUoInJhbmRvbUZvcmVzdCIpICU+JQogIHNldF9tb2RlKCJyZWdyZXNzaW9uIikKClJGX1BNX21vZGVsCmBgYAoKVGhlbiwgd2UgcHV0IHRoaXMgYWxsIHRvZ2V0aGVyIGludG8gYSBgd29ya2Zsb3dgOiAKCiMjIyMgey5yZWNhbGxfY29kZV9xdWVzdGlvbl9ibG9ja30KPGI+PHU+IFF1ZXN0aW9uIE9wcG9ydHVuaXR5IDwvdT48L2I+CgpTZWUgaWYgeW91IGNhbiBjb21lIHVwIHdpdGggdGhlIGNvZGUgdG8gZG8gdGhpcy4KCiMjIyMKCioqKgo8ZGV0YWlscz4gPHN1bW1hcnk+IENsaWNrIGhlcmUgdG8gcmV2ZWFsIHRoZSBhbnN3ZXIuIDwvc3VtbWFyeT4KCmBgYHtyfQpSRl93ZmxvdyA8LSB3b3JrZmxvd3M6OndvcmtmbG93KCkgJT4lCiAgICAgICAgICAgIHdvcmtmbG93czo6YWRkX3JlY2lwZShSRl9yZWMpICU+JQogICAgICAgICAgICB3b3JrZmxvd3M6OmFkZF9tb2RlbChSRl9QTV9tb2RlbCkKCmBgYAo8L2RldGFpbHM+IAoqKioKCmBgYHtyfQpSRl93ZmxvdwpgYGAKCgpGaW5hbGx5LCB3ZSBmaXQgdGhlIGRhdGEgdG8gdGhlIG1vZGVsOgoKIyMjIyB7LnJlY2FsbF9jb2RlX3F1ZXN0aW9uX2Jsb2NrfQo8Yj48dT4gUXVlc3Rpb24gT3Bwb3J0dW5pdHkgPC91PjwvYj4KCkRvIHlvdSByZWNhbGwgaG93IHRvIGRvIHRoaXM/CgojIyMjCgoqKioKPGRldGFpbHM+IDxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHJldmVhbCB0aGUgYW5zd2VyLiA8L3N1bW1hcnk+CgpgYGB7cn0KUkZfd2Zsb3dfZml0IDwtIHBhcnNuaXA6OmZpdChSRl93ZmxvdywgZGF0YSA9IHRyYWluX3BtKQpgYGAKPC9kZXRhaWxzPiAKKioqCgpgYGB7cn0KUkZfd2Zsb3dfZml0CmBgYAoKTGV0J3MgdGFrZSBhIGxvb2sgYXQgdGhlIHRvcCAxMCBjb250cmlidXRpbmcgdmFyaWFibGVzOgoKIyMjIyB7LnJlY2FsbF9jb2RlX3F1ZXN0aW9uX2Jsb2NrfQo8Yj48dT4gUXVlc3Rpb24gT3Bwb3J0dW5pdHkgPC91PjwvYj4KClNlZSBpZiB5b3UgY2FuIHJlY2FsbCBob3cgdG8gZG8gdGhpcy4KCiMjIyMKCmBgYHtyLCBlY2hvID0gRkFMU0V9ClJGX3dmbG93X2ZpdCAlPiUgCiAgcHVsbF93b3JrZmxvd19maXQoKSAlPiUgCiAgdmlwKG51bV9mZWF0dXJlcyA9IDEwKQoKYGBgCgoKKioqCjxkZXRhaWxzPiA8c3VtbWFyeT4gQ2xpY2sgaGVyZSB0byByZXZlYWwgdGhlIGFuc3dlci4gPC9zdW1tYXJ5PgoKYGBge3J9ClJGX3dmbG93X2ZpdCAlPiUgCiAgcHVsbF93b3JrZmxvd19maXQoKSAlPiUgCiAgdmlwKG51bV9mZWF0dXJlcyA9IDEwKQpgYGAKPC9kZXRhaWxzPgoqKioKCgpJbnRlcmVzdGluZyEgSW4gdGhlIHByZXZpb3VzIG1vZGVsIHRoZSBDTUFRIHZhbHVlcyBhbmQgdGhlIHN0YXRlIHdoZXJlIHRoZSBtb25pdG9yIHdhcyBsb2NhdGVkIHdlcmUgYWxzbyB0aGUgdG9wIHR3byBtb3N0IGltcG9ydGFudCwgaG93ZXZlciBwcmVkaWN0b3JzIGFib3V0IGVkdWNhdGlvbiBsZXZlbHMgb2YgdGhlIGNvbW11bml0aWVzIHdoZXJlIHRoZSBtb25pdG9yIHdhcyBsb2NhdGVkIHdhcyBhbW9uZyB0aGUgdG9wIG1vc3QgaW1wb3J0YW50LiBOb3cgd2Ugc2VlIHRoYXQgcG9wdWxhdGlvbiBkZW5zaXR5IGFuZCBwcm94aW1pdHkgdG8gc291cmNlcyBvZiBlbWlzc2lvbnMgYW5kIHJvYWRzIGFyZSBhbW9uZyB0aGUgdG9wIHRlbi4KCgpOb3cgbGV0J3MgdGFrZSBhIGxvb2sgYXQgbW9kZWwgcGVyZm9ybWFuY2UgYnkgZml0dGluZyB0aGUgZGF0YSB1c2luZyBjcm9zcyB2YWxpZGF0aW9uOgoKIyMjIyB7LnJlY2FsbF9jb2RlX3F1ZXN0aW9uX2Jsb2NrfQo8Yj48dT4gUXVlc3Rpb24gT3Bwb3J0dW5pdHkgPC91PjwvYj4KClNlZSBpZiB5b3UgY2FuIHJlY2FsbCBob3cgdG8gZG8gdGhpcy4KCiMjIyMKCioqKgo8ZGV0YWlscz4gPHN1bW1hcnk+IENsaWNrIGhlcmUgdG8gcmV2ZWFsIHRoZSBhbnN3ZXIuIDwvc3VtbWFyeT4KCmBgYHtyLCBldmFsID0gRkFMU0V9CnNldC5zZWVkKDQ1NikKcmVzYW1wbGVfUkZfZml0IDwtIHR1bmU6OmZpdF9yZXNhbXBsZXMoUkZfd2Zsb3csIHZmb2xkX3BtKQpjb2xsZWN0X21ldHJpY3MocmVzYW1wbGVfUkZfZml0KQpgYGAKCjwvZGV0YWlscz4KKioqCgpgYGB7ciwgZWNobyA9IEZBTFNFfQpzZXQuc2VlZCg0NTYpCnJlc2FtcGxlX1JGX2ZpdCA8LSB0dW5lOjpmaXRfcmVzYW1wbGVzKFJGX3dmbG93LCB2Zm9sZF9wbSkKY29sbGVjdF9tZXRyaWNzKHJlc2FtcGxlX1JGX2ZpdCkKYGBgCgpOb3cgbGV0J3MgY29tcGFyZSB0aGUgcGVyZm9ybWFuY2Ugb2YgdGhpcyBtb2RlbCB3aXRoIG91ciBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbDoKCmBgYHtyfQojIG91ciBpbml0aWFsIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsOgpjb2xsZWN0X21ldHJpY3MocmVzYW1wbGVfZml0KQpgYGAKCk9LLCBzbyBvdXIgZmlyc3QgbW9kZWwgaGFkIGEgbWVhbiBgcm1zZWAgdmFsdWUgb2YgMi4xNy4KSXQgbG9va3MgbGlrZSB0aGUgcmFuZG9tIGZvcmVzdCBtb2RlbCBoYWQgIGEgbXVjaCBsb3dlciBgcm1zZWAgdmFsdWUgb2YgMS43Mi4KCiMjIyMgey50aGlua19xdWVzdGlvbl9ibG9ja30KPGI+PHU+IFF1ZXN0aW9uIE9wcG9ydHVuaXR5IDwvdT48L2I+CgpEbyB5b3UgcmVjYWxsIGhvdyB0aGUgUk1TRSBpcyBjYWxjdWxhdGVkPwoKIyMjIwoKKioqCgo8ZGV0YWlscz4gPHN1bW1hcnk+IENsaWNrIGhlcmUgdG8gcmV2ZWFsIHRoZSBhbnN3ZXIuIDwvc3VtbWFyeT4KJCRSTVNFID0gXHNxcnR7XGZyYWN7XHN1bV97aT0xfV57bn17KFxoYXR7eV90fS0geV90KX1eMn17bn19JCQKPC9kZXRhaWxzPiAKCklmIHdlIHR1bmVkIG91ciByYW5kb20gZm9yZXN0IG1vZGVsIGJhc2VkIG9uIHRoZSBudW1iZXIgb2YgdHJlZXMgb3IgdGhlIHZhbHVlIGZvciBgbXRyeWAgKHdoaWNoIGlzICJUaGUgbnVtYmVyIG9mIHByZWRpY3RvcnMgdGhhdCB3aWxsIGJlIHJhbmRvbWx5IHNhbXBsZWQgYXQgZWFjaCBzcGxpdCB3aGVuIGNyZWF0aW5nIHRoZSB0cmVlIG1vZGVscyIpLCB3ZSBtaWdodCBnZXQgYSBtb2RlbCB3aXRoIGV2ZW4gYmV0dGVyIHBlcmZvcm1hbmNlLgoKSG93ZXZlciwgb3VyIGNyb3NzIHZhbGlkYXRlZCBtZWFuIHJtc2UgdmFsdWUgb2YgMS43MiBpcyBxdWl0ZSBnb29kIGJlY2F1c2Ugb3VyIHJhbmdlIG9mIHRydWUgb3V0Y29tZSB2YWx1ZXMgaXMgbXVjaCBsYXJnZXI6IChgciByb3VuZChyYW5nZSh0ZXN0X3BtJHZhbHVlKSwzKWApLgoKCiMjICoqTW9kZWwgdHVuaW5nKioKKioqCgpbSHlwZXJwYXJhbWV0ZXJzXShodHRwczovL21hY2hpbmVsZWFybmluZ21hc3RlcnkuY29tL2RpZmZlcmVuY2UtYmV0d2Vlbi1hLXBhcmFtZXRlci1hbmQtYS1oeXBlcnBhcmFtZXRlci8pIGFyZSBvZnRlbiB0aGluZ3MgdGhhdCB3ZSBuZWVkIHRvIHNwZWNpZnkgYWJvdXQgYSBtb2RlbC4gRm9yIGV4YW1wbGUsIHRoZSBudW1iZXIgb2YgcHJlZGljdG9yIHZhcmlhYmxlcyAob3IgZmVhdHVyZXMpIHRoYXQgd2lsbCBiZSByYW5kb21seSBzYW1wbGVkIGF0IGVhY2ggc3BsaXQgd2hlbiBjcmVhdGluZyB0aGUgdHJlZSBtb2RlbHMgY2FsbGVkIGBtdHJ5YCBpcyBhIGh5cGVycGFyYW1ldGVyLiBUaGUgZGVmYXVsdCBudW1iZXIgZm9yIHJlZ3Jlc3Npb24gYW5hbHlzZXMgaXMgdGhlIG51bWJlciBvZiBwcmVkaWN0b3JzIGRpdmlkZWQgYnkgMy4gSW5zdGVhZCBvZiBhcmJpdHJhcmlseSBzcGVjaWZ5aW5nIHRoaXMsIHdlIGNhbiB0cnkgdG8gZGV0ZXJtaW5lIHRoZSBiZXN0IG9wdGlvbiBmb3IgbW9kZWwgcGVyZm9ybWFuY2UgYnkgYSBwcm9jZXNzIGNhbGxlZCB0dW5pbmcuIAoKCk5vdyBsZXQncyB0cnkgc29tZSB0dW5pbmcuCgpMZXQncyB0YWtlIGEgY2xvc2VyIGxvb2sgYXQgdGhlIGBtdHJ5YCBhbmQgYG1pbl9uYCBoeXBlcnBhcmFtZXRycyBpbiBvdXIgUmFuZG9tIEZvcmVzdCBtb2RlbC4KCldlIGFyZW4ndCBleGFjdGx5IHN1cmUgd2hhdCB2YWx1ZXMgb2YgYG10cnlgIGFuZCBgbWluX25gIGFjaGlldmUgZ29vZCBhY2N1cmFjeSB5ZXQga2VlcCBvdXIgbW9kZWwgZ2VuZXJhbGl6YWJsZSBmb3Igb3RoZXIgZGF0YS4KClRoaXMgaXMgd2hlbiBvdXIgY3Jvc3MgdmFsaWRhdGlvbiBtZXRob2RzIGJlY29tZSByZWFsbHkgaGFuZHkgYmVjYXVzZSBub3cgd2UgY2FuIHRlc3Qgb3V0IGRpZmZlcmVudCB2YWx1ZXMgZm9yIGVhY2ggb2YgdGhlc2UgaHlwZXJwYXJhbWV0ZXJzIHRvIGFzc2VzcyB3aGF0IHZhbHVlcyBzZWVtIHRvIHdvcmsgYmVzdCBmb3IgbW9kZWwgcGVyZm9ybWFuY2Ugb24gdGhlc2UgcmVzYW1wbGVzIG9mIG91ciB0cmFpbmluZyBzZXQgZGF0YS4KClByZXZpb3VzbHkgd2Ugc3BlY2lmaWVkIG91ciBtb2RlbCBsaWtlIHNvOgpgYGB7cn0KUkZfUE1fbW9kZWwgPC0gCiAgcGFyc25pcDo6cmFuZF9mb3Jlc3QobXRyeSA9IDEwLCBtaW5fbiA9IDMpICU+JQogIHNldF9lbmdpbmUoInJhbmRvbUZvcmVzdCIpICU+JQogIHNldF9tb2RlKCJyZWdyZXNzaW9uIikKClJGX1BNX21vZGVsCmBgYApOb3cgaW5zdGVhZCBvZiBzcGVjaWZ5aW5nIGEgdmFsdWUgZm9yIHRoZSBgbXRyeWAgYW5kIGBtaW5fbmAgYXJndW1lbnRzLCB3ZSBjYW4gdXNlIHRoZSBgdHVuZSgpYCBmdW5jdGlvbiBvZiB0aGUgYHR1bmVgIHBhY2thZ2UgbGlrZSBzbzogYG10cnkgPSB0dW5lKClgLiBUaGlzIGluZGljYXRlcyB0aGF0IHRoZXNlIGh5cGVycGFyYW1ldGVycyBhcmUgdG8gYmUgdHVuZWQuIAoKYGBge3J9Cgp0dW5lX1JGX21vZGVsIDwtIHJhbmRfZm9yZXN0KG10cnkgPSB0dW5lKCksIG1pbl9uID0gdHVuZSgpKSAlPiUKICBzZXRfZW5naW5lKCJyYW5kb21Gb3Jlc3QiKSAlPiUKICBzZXRfbW9kZSgicmVncmVzc2lvbiIpCiAgICAKCnR1bmVfUkZfbW9kZWwKCmBgYAoKCkFnYWluIHdlIHdpbGwgYWRkIHRoaXMgdG8gYSB3b3JrZmxvdywgdGhlIG9ubHkgZGlmZmVyZW5jZSBoZXJlIGlzIHRoYXQgd2UgYXJlIHVzaW5nIGEgZGlmZmVyZW50IG1vZGVsIHNwZWNpZmljYXRpb24gd2l0aCBgdHVuZV9SRl9tb2RlbGAgaW5zdGVhZCBvZiBgUkZfbW9kZWxgOgoKYGBge3J9CgpSRl90dW5lX3dmbG93IDwtIHdvcmtmbG93czo6d29ya2Zsb3coKSAlPiUKICAgICAgICAgICAgd29ya2Zsb3dzOjphZGRfcmVjaXBlKFJGX3JlYykgJT4lCiAgICAgICAgICAgIHdvcmtmbG93czo6YWRkX21vZGVsKHR1bmVfUkZfbW9kZWwpClJGX3R1bmVfd2Zsb3cKCmBgYAoKCk5vdyB3ZSBjYW4gdXNlIHRoZSBgdHVuZV9ncmlkKClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZWAgcGFja2FnZSB0byBldmFsdWF0ZSBkaWZmZXJlbnQgY29tYmluYXRpb25zIG9mIHZhbHVlcyBmb3IgYG10cnlgIGFuZCBgbWluX25gIHVzaW5nIG91ciBjcm9zcyB2YWxpZGF0aW9uIHNhbXBsZXMgb2Ygb3VyIHRyYWluaW5nIHNldCAoYHZmb2xkX3BtYCkgdG8gc2VlIHdoYXQgY29tYmluYXRpb24gb2YgdmFsdWVzIHBlcmZvcm1zIGJlc3QuCgpUbyB1c2UgdGhpcyBmdW5jdGlvbiB3ZSB3aWxsIHNwZWNpZnkgdGhlIHdvcmtmbG93IHVzaW5nIHRoZSBgb2JqZWN0YCBhcmd1bWVudCAgYW5kIHRoZSBzYW1wbGVzIHRvIHVzZSB1c2luZyB0aGUgYHJlc2FtcGxlc2AgYXJndW1lbnQuIFRoZSBgZ3JpZGAgYXJndW1lbnQgc3BlY2lmaWVzIGhvdyBtYW55IHBvc3NpYmxlIG9wdGlvbnMgZm9yIGVhY2ggYXJndW1lbnQgc2hvdWxkIGJlIGF0dGVtcHRlZC4KCkJ5IGRlZmF1bHQgMTAgZGlmZmVyZW50IHZhbHVlcyB3aWxsIGJlIGF0dGVtcHRlZCBmb3IgZWFjaCBoeXBlcnBhcmFtZXRlciB0aGF0IGlzIGJlaW5nIHR1bmVkLgoKV2UgY2FuIHVzZSB0aGUgYGRvUGFyYWxsZWxgIHBhY2thZ2UgdG8gYWxsb3cgdXMgdG8gZml0IGFsbCB0aGVzZSBtb2RlbHMgdG8gb3VyIGNyb3NzIHZhbGlkYXRpb24gc2FtcGxlcyBmYXN0ZXIuIFNvIGlmIHlvdSB3ZXJlIHBlcmZvcm1pbmcgdGhpcyBvbiBhIGNvbXB1dGVyIHdpdGggbXVsdGlwbGUgY29yZXMgb3IgcHJvY2Vzc29ycywgdGhlbiBkaWZmZXJlbnQgbW9kZWxzIHdpdGggZGlmZmVyZW50IGh5cGVycGFyYW1ldGVyIHZhbHVlcyBjYW4gYmUgZml0IHRvIHRoZSBjcm9zcyB2YWxpZGF0aW9uIHNhbXBsZXMgc2ltdWx0YW5lb3VzbHkgYWNyb3NzIGRpZmZlcmVudCBjb3JlcyBvciBwcm9jZXNzb3JzLiAKCllvdSBjYW4gc2VlIGhvdyBtYW55IGNvcmVzIHlvdSBoYXZlIGFjY2VzcyB0byBvbiB5b3VyIHN5c3RlbSB1c2luZyB0aGUgYGRldGVjdENvcmVzKClgIGZ1bmN0aW9uIGluIHRoZSBgcGFyYWxsZWxgIHBhY2thZ2UuIAoKYGBge3J9CnBhcmFsbGVsOjpkZXRlY3RDb3JlcygpCmBgYAoKVGhlIGByZWdpc3RlckRvUGFyYWxsZWwoKWAgZnVuY3Rpb24gd2lsbCB1c2UgdGhlIG51bWJlciBmb3IgY29yZXMgc3BlY2lmaWVkIHVzaW5nIHRoZSBgY29yZXM9YCBhcmd1ZW1lbnQsIG9yIGl0IHdpbGwgYXNzaWduIGl0IGF1dG9tYXRpY2FsbHkgdG8gb25lLWhhbGYgb2YgdGhlIG51bWJlciBvZiBjb3JlcyBkZXRlY3RlZCBieSB0aGUgYHBhcmFsbGVsYCBwYWNrYWdlLiAKCldlIG5lZWQgdG8gdXNlIGBzZXQuc2VlZCgpYCBoZXJlIGJlY2F1c2UgdGhlIHZhbHVlcyBjaG9zZW4gZm9yIGBtdHJ5YCBhbmQgYG1pbl9uYCBtYXkgdmFyeSBpZiB3ZSBwcmVmb3JtIHRoaXMgZXZhbHVhdGlvbiBhZ2FpbiBiZWNhdXNlIHRoZXkgYXJlIGNob3NlbiBzZW1pLXJhbmRvbWx5IChtZWFuaW5nIHRoYXQgdGhleSBhcmUgd2l0aGluIGEgcmFuZ2Ugb2YgcmVhc29uYWJsZSB2YWx1ZXMgYnV0IHN0aWxsIHJhbmRvbSkuCgpOb3RlOiB0aGlzIHN0ZXAgd2lsbCB0YWtlIHNvbWUgdGltZS4KCmBgYHtyfQpkb1BhcmFsbGVsOjpyZWdpc3RlckRvUGFyYWxsZWwoY29yZXM9MikKc2V0LnNlZWQoMTIzKQp0dW5lX1JGX3Jlc3VsdHMgPC0gdHVuZV9ncmlkKG9iamVjdCA9IFJGX3R1bmVfd2Zsb3csIHJlc2FtcGxlcyA9IHZmb2xkX3BtLCBncmlkID0gMjApCnR1bmVfUkZfcmVzdWx0cwpgYGAKCgpTZWUgW3RoZSB0dW5lIGdldHRpbmcgc3RhcnRlZCBndWlkZSBdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vdHVuZS9hcnRpY2xlcy9nZXR0aW5nX3N0YXJ0ZWQuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBpbXBsZW1lbnRpbmcgdGhpcyBpbiBgdGlkeW1vZGVsc2AuCgpJZiB5b3Ugd2FudGVkIG1vcmUgY29udHJvbCBvdmVyIHRoaXMgcHJvY2VzcyB5b3UgY291bGQgc3BlY2lmeSBob3cgdGhlIGRpZmZlcmVudCBwb3NzaWJsZSBvcHRpb25zIGZvciBgbXRyeWAgYW5kIGBtaW5fbmAgaW4gdGhlIGB0dW5lX2dyaWQoKWAgZnVuY3Rpb24gdXNpbmcgdGhlIGBncmlkXyooKWAgZnVuY3Rpb25zIG9mIHRoZSBgZGlhbHNgIHBhY2thZ2UgdG8gY3JlYXRlIGEgbW9yZSBzcGVjaWZpYyBncmlkLgoKQmUgZGVmYXVsdCB0aGUgdmFsdWVzIGZvciB0aGUgaHlwZXJwYXJhbWV0ZXJzIGJlaW5nIHR1bmVkIGFyZSBjaG9zZW4gc2VtaS1yYW5kb21seSAobWVhbmluZyB0aGF0IHRoZXkgYXJlIHdpdGhpbiBhIHJhbmdlIG9mIHJlYXNvbmFibGUgdmFsdWVzIGJ1dCBzdGlsbCByYW5kb20pLi4KCgpOb3cgd2UgY2FuIHVzZSB0aGUgYGNvbGxlY3RfbWV0cmljcygpYCBmdW5jdGlvbiBhZ2FpbiB0byB0YWtlIGEgbG9vayBhdCB3aGF0IGhhcHBlbmVkIHdpdGggb3VyIGNyb3NzIHZhbGlkYXRpb24gdGVzdHMuIFdlIGNhbiBzZWUgdGhlIGRpZmZlcmVudCB2YWx1ZXMgY2hvc2VuIGZvciBgbXRyeWAgYW5kIGBtaW5fbmAgYW5kIHRoZSBtZWFuIHJtc2UgYW5kIHJzcSB2YWx1ZXMgYWNyb3NzIHRoZSBjcm9zcyB2YWxpZGF0aW9uIHNhbXBsZXMuCgpgYGB7cn0KdHVuZV9SRl9yZXN1bHRzJT4lCiAgY29sbGVjdF9tZXRyaWNzKCkKYGBgCgpXZSBjYW4gbm93IHVzZSB0aGUgYHNob3dfYmVzdCgpYCBmdW5jdGlvbiBhcyBpdCB3YXMgdHJ1bHkgaW50ZW5kZWQsIHRvIHNlZSB3aGF0IHZhbHVlcyBmb3IgYG1pbl9uYCBhbmQgYG10cnlgIHJlc3VsdGVkIGluIHRoZSBiZXN0IHBlcmZvcm1hbmNlLgoKYGBge3J9CnNob3dfYmVzdCh0dW5lX1JGX3Jlc3VsdHMsIG1ldHJpYyA9ICJybXNlIiwgbiA9MSkKYGBgClRoZXJlIHdlIGhhdmUgaXQuLi4gbG9va3MgbGlrZSBhbiBgbXRyeWAgb2YgMTcgYW5kIGBtaW5fbmAgb2YgNCBoYWQgdGhlIGJlc3QgYHJtc2VgIHZhbHVlLiBZb3UgY2FuIHZlcmlmeSB0aGlzIGluIHRoZSBhYm92ZSBvdXRwdXQsIGJ1dCBpdCBpcyBlYXNpZXIgdG8ganVzdCBwdWxsIHRoaXMgcm93IG91dCB1c2luZyB0aGlzIGZ1bmN0aW9uLiBXZSBjYW4gc2VlIHRoYXQgdGhlIG1lYW4gYHJtc2VgIHZhbHVlIGFjcm9zcyB0aGUgY3Jvc3MgdmFsaWRhdGlvbiBzZXRzIHdhcyAxLjcxMi4gQmVmb3JlIHR1bmluZyBpdCB3YXMgMS43MjUgIHdpdGggYSBzaW1pbGFyIGBzdGRfZXJyYCBzbyB0aGUgcGVyZm9ybWFuY2Ugd2FzIHZlcnkgc2xpZ2h0bHkgaW1wcm92ZWQuCgoKIyMgKipGaW5hbCBtb2RlbCBwZXJmb3JtYW5jZSBldmFsdWF0aW9uKioKKioqCgpOb3cgdGhhdCB3ZSBoYXZlIGRlY2lkZWQgdGhhdCB3ZSBoYXZlIHJlYXNvbmFibGUgcGVyZm9ybWFuY2Ugd2l0aCBvdXIgdHJhaW5pbmcgZGF0YSwgd2UgY2FuIHN0b3AgYnVpbGRpbmcgb3VyIG1vZGVsIGFuZCBldmFsdWF0ZSBwZXJmb3JtYW5jZSB3aXRoIG91ciB0ZXN0aW5nIGRhdGEuIAoKSGVyZSwgd2Ugd2lsbCB1c2UgdGhlIHJhbmRvbSBmb3Jlc3QgbW9kZWwgdGhhdCB3ZSBidWlsdCB0byBwcmVkaWN0IHZhbHVlcyBmb3IgdGhlIG1vbml0b3JzIGluIHRoZSB0ZXN0aW5nIGRhdGEgYW5kIHdlIHdpbGwgdXNlIHRoZSB2YWx1ZXMgZm9yIGBtdHJ5YCBhbmQgYG1pbl9uYCB0aGF0IHdlIGp1c3QgZGV0ZXJtaW5lZCBiYXNlZCBvbiBvdXIgdHVuaW5nIGFuYWx5c2lzIHRvIGFjaGlldmUgdGhlIGJlc3QgcGVyZm9ybWFuY2UuCgpTbywgZmlyc3Qgd2UgbmVlZCB0byBzcGVjaWZ5IHRoZXNlIHZhbHVlcyBpbiBhIHdvcmtmbG93LiBXZSBjYW4gdXNlIHRoZSBgc2VsZWN0X2Jlc3QoKWAgZnVuY3Rpb24gb2YgdGhlIGB0dW5lYCBwYWNrYWdlIHRvIGdyYWIgdGhlIHZhbHVlcyB0aGF0IHdlcmUgZGV0ZXJtaW5lZCB0byBiZSBiZXN0IGZvciBgbXRyeWAgYW5kIGBtaW5fbmAuCgoKCmBgYHtyfQoKdHVuZWRfUkZfdmFsdWVzPC0gc2VsZWN0X2Jlc3QodHVuZV9SRl9yZXN1bHRzLCAicm1zZSIpCnR1bmVkX1JGX3ZhbHVlcwpgYGAKCk5vdyB3ZSBjYW4gZmluYWxpemUgdGhlIG1vZGVsL3dvcmtmbG93IHRoYXQgd2Ugd2UgdXNlZCBmb3IgdHVuaW5nIHdpdGggdGhlc2UgdmFsdWVzLgoKCmBgYHtyfQpSRl90dW5lZF93ZmxvdyA8LVJGX3R1bmVfd2Zsb3cgJT4lCiAgdHVuZTo6ZmluYWxpemVfd29ya2Zsb3codHVuZWRfUkZfdmFsdWVzKQpgYGAKCgpXaXRoIHRoZSBgd29ya2Zsb3dzYCBwYWNrYWdlLCB3ZSBjYW4gdXNlIHRoZSBzcGxpdHRpbmcgaW5mb3JtYXRpb24gZm9yIG91ciBvcmlnaW5hbCBkYXRhIGBwbV9zcGxpdGAgdG8gZml0IHRoZSBmaW5hbCBtb2RlbCBvbiB0aGUgZnVsbCB0cmFpbmluZyBzZXQgYW5kIGFsc28gb24gdGhlIHRlc3RpbmcgZGF0YSB1c2luZyB0aGUgYGxhc3RfZml0KClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZWAgcGFja2FnZS4gTm8gcHJlLXByb2Nlc3Npbmcgc3RlcHMgYXJlIHJlcXVpcmVkLgoKVGhlIHJlc3VsdHMgd2lsbCBzaG93IHRoZSBwZXJmb3JtYW5jZSB1c2luZyB0aGUgdGVzdGluZyBkYXRhLgoKCmBgYHtyfQpvdmVyYWxsZml0IDwtdHVuZTo6bGFzdF9maXQoUkZfdHVuZWRfd2Zsb3csIHBtX3NwbGl0KQogIyBvcgpvdmVyYWxsZml0IDwtUkZfd2Zsb3cgJT4lCiAgdHVuZTo6bGFzdF9maXQocG1fc3BsaXQpCmBgYAoKVGhlIGBvdmVyYWxsZml0YCBvdXRwdXQgaGFzIGEgbG90IG9mIHJlYWxseSB1c2VmdWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1vZGVsLCB0aGUgdGVzdGluZyBhbmQgdHJhaW5pbmcgZGF0YSBzcGxpdCwgYW5kIHRoZSBwcmVkaWN0aW9ucyBmb3IgdGhlIHRlc3RpbmcgZGF0YS4KClRvIHNlZSB0aGUgcGVyZm9ybWFuY2Ugb24gdGhlIHRlc3QgZGF0YSB3ZSBjYW4gdXNlIHRoZSBgY29sbGVjdF9tZXRyaWNzKClgIGZ1bmN0aW9uIGxpa2Ugd2UgZGlkIGJlZm9yZS4KYGBge3J9CiAgY29sbGVjdF9tZXRyaWNzKG92ZXJhbGxmaXQpCiAKYGBgCgpBd2Vzb21lISBXZSBjYW4gc2VlIHRoYXQgb3VyIHJtc2Ugb2YgMS40NCBpcyBxdWl0ZSBzaW1pbGFyIHdpdGggb3VyIHRlc3RpbmcgZGF0YSBjcm9zcyB2YWxpZGF0aW9uIHNldHMuIFdlIGFjaGlldmVkIHF1aXRlIGdvb2QgcGVyZm9ybWFuY2UsIHdoaWNoIHN1Z2dlc3RzIHRoYXQgd2Ugd291bGQgY291bGQgcHJlZGljdCBvdGhlciBsb2NhdGlvbnMgd2l0aCBtb3JlIHNwYXJzZSBtb25pdG9yaW5nIGJhc2VkIG9uIG91ciBwcmVkaWN0b3JzIHdpdGggcmVhc29uYWJsZSBhY2N1cmFjeS4KCk5vdyBpZiB5b3Ugd2FudGVkIHRvIHRha2UgYSBsb29rIGF0IHRoZSBwcmVkaWN0ZWQgdmFsdWVzIGZvciB0aGUgdGVzdCBzZXQgKHRoZSAyOTIgcm93cyB3aXRoIHByZWRpY3Rpb25zIG91dCBvZiB0aGUgODc2IG9yaWdpbmFsIG1vbml0b3IgdmFsdWVzKSB5b3UgY2FuIHVzZSB0aGUgIGBjb2xsZWN0X3ByZWRpY3Rpb25zKClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZSgpYCBwYWNrYWdlOgoKYGBge3J9CnRlc3RfcHJlZGljdGlvbnMgPC1jb2xsZWN0X3ByZWRpY3Rpb25zKG92ZXJhbGxmaXQpCmBgYAoKYGBge3IsIGV2YWwgPSBGQUxTRX0KdGVzdF9wcmVkaWN0aW9ucwpgYGAKCiMjIyMgey5zY3JvbGxhYmxlIH0KYGBge3IsIGVjaG8gPUZBTFNFfQp0ZXN0X3ByZWRpY3Rpb25zICU+JQogIHByaW50KG4gPSAxZTMpCmBgYAoKIyMjIwoKTmljZSEKCiMgKipEYXRhIFZpc3VhbGl6YXRpb24qKgoqKioKCk91ciBtYWluIHF1ZXN0aW9uIGZvciB0aGlzIGNhc2Ugc3R1ZHkgd2FzOiAgCgo+IENhbiB3ZSBwcmVkaWN0IGFubnVhbCBhdmVyYWdlIGFpciBwb2xsdXRpb24gY29uY2VudHJhdGlvbnMgYXQgdGhlIGdyYW51bGFyaXR5IG9mIHppcCBjb2RlIHJlZ2lvbmFsIGxldmVscyB1c2luZyBwcmVkaWN0b3JzIHN1Y2ggYXMgZGF0YSBhYm91dCBwb3B1bGF0aW9uIGRlbnNpdHksIHVyYmFuaXphdGlvbiwgcm9hZCBkZW5zaXR5LCBhcyB3ZWxsIGFzLCBzYXRlbGxpdGUgcG9sbHV0aW9uIGRhdGEgYW5kIGNoZW1pY2FsIG1vZGVsaW5nIGRhdGE/CgpUaHVzIGZhciwgd2UgaGF2ZSBidWlsZCBhIG1hY2hpbmUgbGVhcm5pbmcgKE1MKSBtb2RlbCB0byBwcmVkaWN0IGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIGFpciBwb2xsdXRpb24gbGV2ZWxzIGJhc2VkIG9uIG91ciBwcmVkaWN0b3IgdmFyaWFibGVzIChvciBmZWF0dXJlcykuCgpOb3csIGxldCdzIG1ha2UgYSBwbG90IG9mIG91ciBwcmVkaWN0ZWQgb3V0Y29tZSB2YWx1ZXMgKCRcaGF0e1l9JCkgYW5kIGFjdHVhbCBvdXRjb21lIHZhbHVlcyAkWSQgd2Ugb2JzZXJ2ZWQuIAoKRmlyc3QsIGxldCdzIHN0YXJ0IGJ5IG1ha2luZyBhIHBsb3Qgb2Ygb3VyIG1vbml0b3JzLiAKVG8gZG8gdGhpcywgd2Ugd2lsbCB1c2UgdGhlIGZvbGxvd2luZyBwYWNrYWdlcyB0byBjcmVhdGUgYSBtYXAgb2YgdGhlIFVTOgoKMS4gYHNmYCAtIHRoZSBzaW1wbGUgZmVhdHVyZXMgcGFja2FnZSBoZWxwcyB0byBjb252ZXJ0IGdlb2dyYXBoaWNhbCBjb29yZGluYXRlcyBpbnRvIGBnZW9tZXRyeWAgdmFyaWFibGVzIHdoaWNoIGFyZSB1c2VmdWwgZm9yIG1ha2luZyAyRCBwbG90cwoyLiBgbWFwc2AgLSB0aGlzIHBhY2thZ2UgY29udGFpbnMgZ2VvZ3JhcGhpY2FsIG91dGxpbmVzIGFuZCBwbG90dGluZyBmdW5jdGlvbnMgdG8gY3JlYXRlIHBsb3RzIHdpdGggbWFwcyAKMy4gYHJuYXR1cmFsZWFydGhgLSB0aGlzIGFsbG93cyBmb3IgZWFzeSBpbnRlcmFjdGlvbiB3aXRoIG1hcCBkYXRhIGZyb20gW05hdHVyYWwgRWFydGhdKGh0dHA6Ly93d3cubmF0dXJhbGVhcnRoZGF0YS5jb20vKSB3aGljaCBpcyBhIHB1YmxpYyBkb21haW4gbWFwIGRhdGFzZXQKNC4gYHJnZW9zYCAtIHRoaXMgcGFja2FnZSBpbnRlcmZhY2VzIHdpdGggdGhlIEdlb21ldHJ5IEVuZ2luZS1PcGVuIFNvdXJjZSAoYEdFT1NgKSB3aGljaCBpcyBhbHNvIGhlbHBmdWwgZm9yIGNvb3JkaW5hdGUgY29udmVyc2lvbgoKV2Ugd2lsbCBzdGFydCB3aXRoIGdldHRpbmcgYW4gb3V0bGluZSBvZiB0aGUgVVMgd2l0aCB0aGUgYG5lX2NvdW50cmllcygpYCBmdW5jdGlvbiBvZiB0aGUgYHJuYXR1cmFsZWFydGhgIHBhY2thZ2Ugd2hpY2ggd2lsbCByZXR1cm4gcG9seWdvbnMgb2YgdGhlIGNvdW50cmllcyBpbiB0aGUgW05hdHVyYWwgRWFydGhdKGh0dHA6Ly93d3cubmF0dXJhbGVhcnRoZGF0YS5jb20vKSBkYXRhc2V0LgoKYGBge3J9Cgp3b3JsZCA8LSBuZV9jb3VudHJpZXMoc2NhbGUgPSAibWVkaXVtIiwgcmV0dXJuY2xhc3MgPSAic2YiKQpnbGltcHNlKHdvcmxkKQoKYGBgCgoKSGVyZSB5b3UgY2FuIHNlZSB0aGUgZGF0YSBhYm91dCB0aGUgY291bnRyaWVzIGluIHRoZSB3b3JsZC4gTm90aWNlIHRoZSBgZ2VvbWV0cnlgIHZhcmlhYmxlLiBUaGlzIGlzIHVzZWQgdG8gY3JlYXRlIHRoZSBvdXRsaW5lcyB0aGF0IHdlIHdhbnQuIAoKTm93IHdlIGNhbiB1c2UgdGhlIGBnZW9tX3NmKClgIGZ1bmN0aW9uIG9mIHRoZSBgZ2dwbG90MmAgcGFja2FnZSB0byBjcmVhdGUgYSB2aXN1YWwgb2Ygc2ltcGxlIGZlYXR1cmUgKHRoZSBnZW9tZXRyeSBjb29yZGluYXRlcyBmb3VuZCBpbiB0aGUgYGdlb21ldHJ5YCB2YXJpYWJsZSkuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSB3b3JsZCkgKwogICAgZ2VvbV9zZigpIAoKYGBgCgpTbyBub3cgd2UgY2FuIHNlZSB0aGF0IHdlIGhhdmUgb3V0bGluZXMgb2YgYWxsIHRoZSBjb3VudHJpZXMgaW4gdGhlIHdvcmxkLgoKV2Ugd2FudCB0byBsaW1pdCB0aGlzIGp1c3QgdG8gdGhlIGNvb3JkaW5hdGVzIGZvciB0aGUgVVMuIFdlIHdpbGwgZG8gdGhpcyBiYXNlZCBvbiB0aGUgY29vcmRpbmF0ZXMgd2UgZm91bmQgb24gV2lraXBlZGlhLiBBY2NvcmRpbmcgdG8gdGhpcyBbbGlua10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGlzdF9vZl9leHRyZW1lX3BvaW50c19vZl90aGVfVW5pdGVkX1N0YXRlcyNXZXN0ZXJubW9zdCl7dGFyZ2V0PSJfYmxhbmsifSwgdGhlc2UgYXJlIHRoZSBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlIGJvdW5kcyBvZiB0aGUgY29udGluZW50YWwgVVM6CgotIHRvcCA9IDQ5LjM0NTc4NjggIyBub3J0aCBsYXQKLSBsZWZ0ID0gLTEyNC43ODQ0MDc5ICMgd2VzdCBsb25nCi0gcmlnaHQgPSAtNjYuOTUxMzgxMiAjIGVhc3QgbG9uZwotIGJvdHRvbSA9ICAyNC43NDMzMTk1ICMgc291dGggbGF0CgpgYGB7cn0KCmdncGxvdChkYXRhID0gd29ybGQpICsKICAgIGdlb21fc2YoKSArCiAgICBjb29yZF9zZih4bGltID0gYygtMTI1LCAtNjYpLCB5bGltID0gYygyNC41LCA1MCksIAogICAgICAgICAgICAgZXhwYW5kID0gRkFMU0UpCmBgYApOb3cgd2UganVzdCBoYXZlIGEgcGxvdCB0aGF0IGlzIG1vc3RseSBsaW1pdGVkIHRvIHRoZSBvdXRsaW5lIG9mIHRoZSBVUy4KCk5vdyB3ZSB3aWxsIHVzZSB0aGUgYGdlb21fcG9pbnQoKWAgZnVuY3Rpb24gb2YgdGhlIGBnZ3Bsb3RgIHBhY2thZ2UgdG8gYWRkIHNjYXR0ZXIgcGxvdCBvbiB0b3Agb2YgdGhlIG1hcC4gV2Ugd2FudCB0byBzaG93IHdoZXJlIHRoZSBtb25pdG9ycyBhcmUgbG9jYXRlZCBiYXNlZCBvbiB0aGUgbGF0aXR1ZGUgYW5kIGxvbmdpdHVkZSB2YWx1ZXMgaW4gdGhlIGRhdGEuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSB3b3JsZCkgKwogICAgZ2VvbV9zZigpICsKICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0xMjUsIC02NiksIHlsaW0gPSBjKDI0LjUsIDUwKSwgCiAgICAgICAgICAgICBleHBhbmQgPSBGQUxTRSkrCiAgICBnZW9tX3BvaW50KGRhdGEgPSBwbSwgYWVzKHggPSBsb24sIHkgPSBsYXQpLCBzaXplID0gMiwgCiAgICAgICAgICAgICAgIHNoYXBlID0gMjMsIGZpbGwgPSAiZGFya3JlZCIpCgpgYGAKTmljZSEKCk5vdyBsZXQncyBhZGQgY291bnR5IGxpbmVzLgoKQ291bnR5IGdyYXBoaWNhbCBkYXRhIGlzIGF2YWlsYWJsZSBmcm9tIHRoZSBgbWFwc2AgcGFja2FnZS4gClRoZSBgc2ZgIHBhY2thZ2Ugd2hpY2ggYWdhaW4gaXMgc2hvcnQgZm9yIHNpbXBsZSBmZWF0dXJlcyBjcmVhdGVzIGEgZGF0YSBmcmFtZSBhYm91dCB0aGlzIGdyYXBoaWNhbCBkYXRhIHNvIHRoYXQgd2UgY2FuIHdvcmsgd2l0aCBpdC4KCmBgYHtyfQpjb3VudGllcyA8LSAKICBzZjo6c3RfYXNfc2YobWFwczo6bWFwKCJjb3VudHkiLCBwbG90ID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IFRSVUUpKQoKY291bnRpZXMKYGBgCgpOb3cgd2Ugd2lsbCB1c2UgdGhpcyBkYXRhIHdpdGhpbiB0aGUgYGdlb21fc2YoKWAgZnVuY3Rpb24gdG8gYWRkIHRoaXMgdG8gb3VyIHBsb3QuICBXZSB3aWxsIGFsc28gYWRkIGEgdGl0bGUgdXNpbmcgdGhlIGBnZ3RpdGxlKClgIGZ1bmN0aW9uLCBhcyB3ZWxsIGFzIHJlbW92ZSBheGlzIHRpY2tzIGFuZCB0aXRsZXMgdXNpbmcgdGhlIGB0aGVtZSgpYCBmdW5jdGlvbiBvZiB0aGUgYGdncGxvdDJgIHBhY2thZ2UuCgpgYGB7cn0KbW9uaXRvcnMgPC0gZ2dwbG90KGRhdGEgPSB3b3JsZCkgKwogICAgZ2VvbV9zZihkYXRhID0gY291bnRpZXMsIGZpbGwgPSBOQSwgY29sb3IgPSBncmF5KC41KSkrCiAgICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0xMjUsIC02NiksIHlsaW0gPSBjKDI0LjUsIDUwKSwgCiAgICAgICAgICAgICBleHBhbmQgPSBGQUxTRSkgKwogICAgZ2VvbV9wb2ludChkYXRhID0gcG0sIGFlcyh4ID0gbG9uLCB5ID0gbGF0KSwgc2l6ZSA9IDIsIAogICAgICAgICAgICAgICBzaGFwZSA9IDIzLCBmaWxsID0gImRhcmtyZWQiKSArCiAgICBnZ3RpdGxlKCJNb25pdG9yIExvY2F0aW9ucyIpICsKICAgIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkKCm1vbml0b3JzCmBgYAoKR3JlYXQhCgpOb3csIGxldCdzIGFkZCBhIGZpbGwgYXQgdGhlIGNvdW50eS1sZXZlbCBmb3IgdGhlIHRydWUgbW9uaXRvciB2YWx1ZXMgb2YgYWlyIHBvbGx1dGlvbi4KCkZpcnN0LCB3ZSBuZWVkIHRvIGdldCB0aGUgY291bnR5IG1hcCBkYXRhIHRoYXQgd2UganVzdCBnb3QgYW5kIG91ciBhaXIgcG9sbHV0aW9uIGRhdGEgdG8gaGF2ZSBzaW1pbGFybHkgZm9ybWF0dGVkIGNvdW50eSBuYW1lcyBzbyB0aGF0IHdlIGNhbiBjb21iaW5lIHRoZSBkYXRhc2V0cyB0b2dldGhlci4KCldlIGNhbiBzZWUgdGhhdCBpbiB0aGUgYGNvdW50eWAgZGF0YSB0aGUgY291bnRpZXMgYXJlIGxpc3RlZCBhZnRlciB0aGUgc3RhdGUgbmFtZSBhbmQgYSBjb21tYS4gSW4gYWRkaXRpb24gdGhleSBhcmUgYWxsIGxvd2VyIGNhc2UuCgoKYGBge3J9CmhlYWQoY291bnRpZXMpCmBgYAoKSW4gY29udHJhc3QsIG91ciBhaXIgcG9sbHV0aW9uIGBwbWAgZGF0YSBzaG93cyBjb3VudGllcyBhcyB0aXRsZXMgd2l0aCB0aGUgZmlyc3QgbGV0dGVyIGFzIHVwcGVyIGNhc2UuIAoKYGBge3J9CmRwbHlyOjpwdWxsKHBtLCBjb3VudHkpICU+JQogIGhlYWQoKQpgYGAKCldlIGNhbiB1c2UgdGhlIGBzZXBhcmF0ZSgpYCBmdW5jdGlvbiBvZiB0aGUgYHRpZHlyYCBwYWNrYWdlIHRvIHNlcGFyYXRlIHRoZSBgSURgIHZhcmlhYmxlIG9mIG91ciBgY291bnRpZXNgIGRhdGEgaW50byB0d28gYHZhcmlhYmxlc2AgYmFzZWQgb24gdGhlIGNvbW1hIGFzIGEgc2VwYXJhdG9yLgoKYGBge3J9CmNvdW50aWVzICU8PiUgCiAgdGlkeXI6OnNlcGFyYXRlKElELCBpbnRvID0gYygic3RhdGUiLCAiY291bnR5IiksIHNlcCA9ICIsIikKCmhlYWQoY291bnRpZXMpCmBgYApOb3cgd2UganVzdCBuZWVkIHRvIG1ha2UgdGhlc2UgbmFtZXMgaW4gdGhlIG5ldyBgY291bnR5YCB2YXJpYWJsZSBvZiB0aGUgYGNvdW50aWVzYCBkYXRhIHRvIGJlIGluIHRpdGxlIGZvcm1hdC4gV2UgY2FuIHVzZSB0aGUgYHN0cl90b190aXRsZSgpYCBmdW5jdGlvbiBvZiB0aGUgYHN0cmluZ3JgIHBhY2thZ2UgdG8gZG8gdGhpcy4gCmBgYHtyfQpjb3VudGllc1tbImNvdW50eSJdXSA8LSBzdHJpbmdyOjpzdHJfdG9fdGl0bGUoY291bnRpZXNbWyJjb3VudHkiXV0pCmBgYAoKR3JlYXQhIE5vdyB0aGUgY291bnR5IGluZm9ybWF0aW9uIGlzIHRoZSBzYW1lIGZvciB0aGUgYGNvdW50aWVzYCBhbmQgYHBtYCBkYXRhLgoKV2UgY2FuIHVzZSB0aGUgYGlubmVyX2pvaW4oKWAgZnVuY3Rpb24gb2YgdGhlIGBkcGx5cmAgcGFja2FnZSB0byBqb2luIHRoZSBkYXRhc2V0cyB0b2dldGhlciBiYXNlZCBvbiB0aGUgYGNvdW50eWAgdmFyaWFibGVzIGluIGVhY2guIFRoaXMgZnVuY3Rpb24gd2lsbCBrZWVwIGFsbCByb3dzIHRoYXQgYXJlIGluIGJvdGggZGF0YXNldHMuCgpgYGB7cn0KbWFwX2RhdGEgPC1kcGx5cjo6aW5uZXJfam9pbihjb3VudGllcywgcG0sIGJ5ID0gImNvdW50eSIpCgpnbGltcHNlKG1hcF9kYXRhKQoKYGBgCk5pY2UhIHdlIGNhbiBzZWUgdGhhdCB3ZSBoYXZlIGFkZCBhIGBnZW9tYCB2YXJpYWJsZSB0byB0aGUgYHBtYCBkYXRhLgoKTm93IHdlIGNhbiB1c2UgdGhpcyB0byBjb2xvciB0aGUgY291bnRpZXMgaW4gb3VyIHBsb3QgYmFzZWQgb24gdGhlIGB2YWx1ZWAgdmFyaWFibGUgb2Ygb3VyIGBwbWAgZGF0YSwgd2hpY2ggeW91IG1heSByZWNhbGwgaXMgdGhlIGFjdHVhbCBtb25pdG9yIGRhdGEgZm9yIGZpbmUgcGFydGljdWxhdGUgYWlyIHBvbGx1dGlvbiBhdCBlYWNoIG1vbml0b3IuIAoKV0UgY2FuIGRvIHNvIHVzaW5nIHRoZSBgc2NhbGVfZmlsbF9ncmFkaWVudG4oKWAgZnVuY3Rpb24gb2YgdGhlIGBnZ3Bsb3QyYCBwYWNrYWdlIHdoaWNoIGNyZWF0ZXMgY29sb3IgZ3JhZGllbnQgYmFzZWQgb24gYSB2YXJpYWJsZS4gSW4gdGhpcyBjYXNlIGl0IGlzIHRoZSB2YXJpYWJsZSB0aGF0IHdhcyBzcGVjaWZpZWQgYXMgdGhlIGBmaWxsYCBpbiB0aGUgYGFlc2AgZnVuY3Rpb24gb2YgdGhlIGBnZW9tX3NmKClgIGZ1bmN0aW9uLiBXZSBzcGVjaWZpZWQgdGhhdCBpdCB3b3VsZCBiZSB0aGUgYHZhbHVlYCB2YXJpYWJsZSBvZiB0aGUgYHBtYCBkYXRhLgoKVGhpcyBgc2NhbGVfZmlsbF9ncmFkaWVudG4oKWAgZnVuY3Rpb24gIGFsc28gYWxsb3dzIHlvdSB0byBzcGVjaWZ5IHRoZSBjb2xvcnMsIHdoYXQgdG8gZG8gYWJvdXQgTkEgdmFsdWVzIChzaG91bGQgdGhleSBiZSBhIHNwZWNpZmljIGNvbG9yIG9yIHRyYW5zcGFyZW50KSBhbmQgdGhlIGJyZWFrcywgbGltaXRzLCBsYWJlbHMgYW5kIG5hbWUvdGl0bGUgb24gdGhlIGxlZ2VuZCBmb3IgdGhlIGNvbG9yIGdyYWRpZW50LiAKCmBgYHtyfQoKdHJ1dGggPC1nZ3Bsb3QoZGF0YSA9IHdvcmxkKSArCiAgY29vcmRfc2YoeGxpbSA9IGMoLTEyNSwgLTY2KSwgeWxpbSA9IGMoMjQuNSwgNTApLCBleHBhbmQgPSBGQUxTRSkrCiAgICBnZW9tX3NmKGRhdGEgPSBtYXBfZGF0YSwgYWVzKGZpbGwgPSB2YWx1ZSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzPXRvcG8uY29sb3JzKDcpLCBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcz1jKDAsMTAsMjApLGxhYmVscz1jKDAsMTAsMjApLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHM9YygwLDIzLjUpLCBuYW1lID0gIlBNIHVnL20zIikgKwogIGdndGl0bGUoIlRydWUgUE0gMi41IGxldmVscyIpICsKICAgIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkKCnRydXRoCgpgYGAKTmljZSEKCk5vdyBsZXQncyBkbyB0aGUgc2FtZSB3aXRoIG91ciBwcmVkaWN0ZWQgb3V0Y29tZSB2YWx1ZXMuCgpMZXQncyBncmFiIGJvdGggdGhlIHRlc3RpbmcgYW5kIHRyYWluaW5nIHByZWRpY3RlZCBvdXRjb21lIHZhbHVlcyBzbyB0aGF0IHdlIGhhdmUgYXMgbXVjaCBkYXRhIGFzIHBvc3NpYmxlLiAKCkZpcnN0IHdlIG5lZWQgdG8gZml0IG91ciB0cmFpbmluZyBkYXRhIHdpdGggb3VyIGZpbmFsIG1vZGVsIHRvIGJlIGFibGUgdG8gZ2V0IHRoZSBwcmVkaWN0aW9ucyBmb3IgdGhlIG1vbml0b3JzIGluY2x1ZGVkIGluIHRoZSB0cmFpbmluZyBzZXQuIFdlIGRpZCB0aGlzIHVzaW5nIHRoZSBgbGFzdF9maXQoKWAgZnVuY3Rpb24sIGJ1dCB0aGUgb3V0cHV0IG9mIHRoaXMgbWFrZXMgaXQgZGlmZmljdWx0IHRvIGdyYWIgdGhlIHByZWRpY3RlZCB2YWx1ZXMgZm9yIHRoZSB0cmFpbmluZyBkYXRhLCBhbmQgaXQgaXMgYWxzbyBkaWZmaWN1bHQgdG8gZ2V0IHRoZSBpZCB2YXJpYWJsZXMgZm9yIHRoZSB0ZXN0aW5nIGRhdGEuIAoKClRodXMgd2Ugd2lsbCB1c2UgdGhlIHBhcnNuaXAgYGZpdCgpYCBhbmQgYHByZWRpY3QoKWAgZnVuY3Rpb25zIG9mIHRoZSBgcGFyc25pcGAgcGFja2FnZSB0byBkbyB0aGlzIGxpa2Ugc286CgojIyMjIHsudGhpbmtfcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBRdWVzdGlvbiBPcHBvcnR1bml0eSA8L3U+PC9iPgoKV2h5IGRvIHdlIG5vdCBuZWVkIHByZS1wcm9jZXNzZWQgZGF0YT8KCiMjIyMKCioqKgoKPGRldGFpbHM+IDxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHJldmVhbCB0aGUgYW5zd2VyLiA8L3N1bW1hcnk+CgpTaW5jZSB3ZSBhcmUgdXNpbmcgYSB3b3JrZmxvdywgdGhlIGRhdGEgd2lsbCBiZSBwcmUtcHJvY2Vzc2VkIHdoZW4gaXQgaXMgZml0IGFzIHdlbGwuCgo8L2RldGFpbHM+CioqKgoKCmBgYHtyfQoKUkZfZmluYWxfdHJhaW5fZml0IDwtIHBhcnNuaXA6OmZpdChSRl90dW5lZF93ZmxvdywgZGF0YSA9IHRyYWluX3BtKQpSRl9maW5hbF90ZXN0X2ZpdCA8LSBwYXJzbmlwOjpmaXQoUkZfdHVuZWRfd2Zsb3csIGRhdGEgPSB0ZXN0X3BtKQoKCnZhbHVlc19wcmVkX3RyYWluIDwtIAogIHByZWRpY3QoUkZfZmluYWxfdHJhaW5fZml0LCB0cmFpbl9wbSkgJT4lIAogIGJpbmRfY29scyh0cmFpbl9wbSAlPiUgc2VsZWN0KHZhbHVlLCBmaXBzLCBjb3VudHksIGlkKSkgCgp2YWx1ZXNfcHJlZF90cmFpbgoKdmFsdWVzX3ByZWRfdGVzdCA8LSAKICBwcmVkaWN0KFJGX2ZpbmFsX3Rlc3RfZml0LCB0ZXN0X3BtKSAlPiUgCiAgYmluZF9jb2xzKHRlc3RfcG0gJT4lIHNlbGVjdCh2YWx1ZSwgZmlwcywgY291bnR5LCBpZCkpIAoKdmFsdWVzX3ByZWRfdGVzdApgYGAKCk5vdyB3ZSBjYW4gY29tYmluZSB0aGlzIGRhdGEgZm9yIHRoZSBwcmVkaWN0aW9ucyBmb3IgYWxsIG1vbml0b3JzIHVzaW5nIHRoZSBgYmluZF9yb3dzKClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2UsIHdoaWNoIHdpbGwgZXNzZW50aWFsbHkgYXBwZW5kIHRoZSBzZWNvbmQgZGF0YXNldCB0byB0aGUgZmlyc3QuCgpgYGB7cn0KYWxsX3ByZWQgPC0gYmluZF9yb3dzKHZhbHVlc19wcmVkX3Rlc3QsIHZhbHVlc19wcmVkX3RyYWluKQoKYWxsX3ByZWQKYGBgCgpHcmVhdCEgYXMgd2UgY2FuIHNlZSB0aGVyZSBhcmUgODc2IHZhbHVlcyBsaWtlIHdlIHdvdWxkIGV4cGVjdCBmb3IgYWxsIG9mIHRoZSBtb25pdG9ycy4gV2UgY2FuIHVzZSB0aGUgYGNvdW50eWAgdmFyaWFibGUgdG8gY29tYmluZSB0aGlzIHdpdGggdGhlIGBjb3VudGllc2AgZGF0YSBsaWtlIHdlIGRpZCB3aXRoIHRoZSBgcG1gIGRhdGEgcHJldmlvdXNseSBzbyB0aGF0IHdlIGNhbiB1c2UgdGhlIGB2YWx1ZWAgdmFyaWFibGUgYXMgYSBjb2xvciBzY2hlbWUgZm9yIG91ciBtYXAuCgoKYGBge3J9Cm1hcF9kYXRhIDwtIGlubmVyX2pvaW4oY291bnRpZXMsIGFsbF9wcmVkLCBieSA9ICJjb3VudHkiKQoKcHJlZCA8LSBnZ3Bsb3QoZGF0YSA9IHdvcmxkKSArCiAgICAgICAgICBjb29yZF9zZih4bGltID0gYygtMTI1LCAtNjYpLCB5bGltID0gYygyNC41LCA1MCksIAogICAgICAgICAgICAgICAgIGV4cGFuZCA9IEZBTFNFKSArCiAgICBnZW9tX3NmKGRhdGEgPSBtYXBfZGF0YSwgYWVzKGZpbGwgPSAucHJlZCkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzPXRvcG8uY29sb3JzKDcpLCBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoMCwxMCwyMCksbGFiZWxzPWMoMCwxMCwyMCksCiAgICAgICAgICAgICAgICAgICAgICAgbGltaXRzPWMoMCwyMy41KSwgbmFtZSA9ICJQTSB1Zy9tMyIpICsKICBnZ3RpdGxlKCJQcmVkaWN0ZWQgUE0gMi41IGxldmVscyIpKwogICAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpKQoKcHJlZApgYGAKCk5vdyB3ZSB3aWxsIHVzZSB0aGUgYHBhdGNod29ya2AgcGFja2FnZSB0byBjb21iaW5lIG91ciBsYXN0IHR3byBwbG90cy4gVGhpcyBhbGxvd3MgdXMgdG8gY29tYmluZSBwbG90cyB1c2luZyB0aGUgYCtgIG9yIHRoZSBgL2AgLiBUaGUgYCtgIHdpbGwgcGxhY2UgcGxvdHMgc2lkZSBieSBzaWRlIGFuZCB0aGUgYC9gIHdpbGwgcGxhY2UgcGxvdHMgdG9wIHRvIGJvdHRvbS4KCgpOb3cgbGV0J3MganVzdCBjb21iaW5lIHRoZSB0cnV0aCBwbG90IGFuZCB0aGUgcHJlZGljdGlvbiBwbG90cyB0b2dldGhlcjoKYGBge3J9CnRydXRoL3ByZWQKCmBgYAoKV2UgY2FuIHNlZSB0aGF0IHRoZSBwcmVkaWN0ZWQgZmluZSBwYXJ0aWNsZSBhaXIgcG9sbHV0aW9uIHZhbHVlcyBpbiAodWcvbTMpIGFyZSBxdWl0ZSBzaW1pbGFyIHRvIHRoZSB0cnVlIHZhbHVlcyBtZWFzdXJlZCBieSB0aGUgYWN0dWFsIGdyYXZpbWV0cmljIG1vbml0b3JzLiBXZSBjYW4gYWxzbyBzZWUgdGhhdCBzb3V0aGVybiBDYWxpZm9ybmlhIGhhcyBzb21lIGxhcmdlIGNvdW50aWVzIHdpdGggd29yc2UgcG9sbHV0aW9uIChhcyB0aGV5IGFyZSB5ZWxsb3cgYW5kIHRodXMgaGF2ZSBtdWNoIGhpZ2hlciBwYXJ0aWN1bGF0ZSBtYXR0ZXIgbGV2ZWxzKS4KCkxldCdzIGFkZCBzb21lIHRleHQgdG8gb3VyIHBsb3QgdG8gZXhwbGFpbiBpdCBhIGJpdCBtb3JlLiBXZSBjYW4gZG8gc28gdXNpbmcgdGhlIGBwbG90X2Fubm90YXRpb24oKWAgZnVuY3Rpb24gb2YgdGhlIGBwYXRjaHdvcmtgIHBhY2thZ2UuIFRoZSBgdGhlbWVgIGFyZ3VtZW50IG9mIHRoaXMgZnVuY3Rpb24gdGFrZXMgdGhlIHNhbWUgdGhlbWUgaW5mb3JtYXRpb24gdXNpbmcgdGhlIGB0aGVtZSgpYCBmdW5jdGlvbiBvZiB0aGUgYGdncGxvdDJgIHBhY2thZ2UgYXMgd2hlbiBjcmVhdGluZyBgZ2dwbG90MmBwbG90cy4KCmBgYHtyfQoodHJ1dGgvcHJlZCkgKyBwbG90X2Fubm90YXRpb24odGl0bGUgPSAiTWFjaGluZSBMZWFybmluZyBNZXRob2RzIEFsbG93IGZvciBQcmVkaWN0aW9uIG9mIEFpciBQb2xsdXRpb24iLCBzdWJ0aXRsZSA9ICJBIHJhbmRvbSBmb3Jlc3QgbW9kZWwgcHJlZGljdHMgdHJ1ZSBtb25pdG9yZWQgbGV2ZWxzIG9mIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIChQTSAyLjUpIGFpciBwb2xsdXRpb24gYmFzZWQgb25cbmRhdGEgYWJvdXQgcG9wdWxhdGlvbiBkZW5zaXR5IGFuZCBvdGhlciBwcmVkaWN0b3JzIHJlYXNvbmFibHkgd2VsbCwgdGh1cyBzdWdnZXN0aW5nIHRoYXQgd2UgY2FuIHByZWRpY3QgbGV2ZWxzXG5vZiBwb2xsdXRpb24gaW4gcGxhY2VzIHdpdGggcG9vciBtb25pdG9yaW5nIiwgdGhlbWUgPSB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTEyLCBmYWNlID0gImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpKQoKYGBgCgoKYGBge3IsIGVjaG8gPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXZhbD1GQUxTRSwgaW5jbHVkZSA9IEZBTFNFfQpwbmcoaGVyZTo6aGVyZSgiaW1nIiwgIm1haW5fcGxvdF9tYXBzLnBuZyIpLCAKICAgIGhlaWdodCA9IDE1MDAsIHdpZHRoID0gMjAwMCwgcmVzID0gMzAwKQoodHJ1dGgvcHJlZCkgKyBwbG90X2Fubm90YXRpb24odGl0bGUgPSAiTWFjaGluZSBMZWFybmluZyBNZXRob2RzIEFsbG93IGZvciBQcmVkaWN0aW9uIG9mIEFpciBQb2xsdXRpb24iLCBzdWJ0aXRsZSA9ICJBIHJhbmRvbSBmb3Jlc3QgbW9kZWwgcHJlZGljdHMgdHJ1ZSBtb25pdG9yZWQgbGV2ZWxzIG9mIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIChQTSAyLjUpIGFpciBwb2xsdXRpb24gYmFzZWQgb25cbmRhdGEgYWJvdXQgcG9wdWxhdGlvbiBkZW5zaXR5IGFuZCBvdGhlciBwcmVkaWN0b3JzIHJlYXNvbmFibHkgd2VsbCwgdGh1cyBzdWdnZXN0aW5nIHRoYXQgd2UgY2FuIHByZWRpY3QgbGV2ZWxzXG5vZiBwb2xsdXRpb24gaW4gcGxhY2VzIHdpdGggcG9vciBtb25pdG9yaW5nIiwgdGhlbWUgPSB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTEyLCBmYWNlID0gImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpKQpkZXYub2ZmKCkKYGBgCgojICoqU3VtbWFyeSoqCioqKgoKIyMgKipTeW5vcHNpcyoqCioqKgoKSW4gdGhpcyBjYXNlIHN0dWR5LCB3ZSBleHBsb3JlZCBncmF2aW1ldHJpYyBtb25pdG9yaW5nIGRhdGEgb2YgZmluZSBwYXJ0aWN1bGF0ZSBtYXR0ZXIgYWlyIHBvbGx1dGlvbiAob3V0Y29tZSB2YXJpYWJsZSkuIApPdXIgZ29hbCB3YXMgdG8gYWJsZSB0byBwcmVkaWN0IGFpciBwb2xsdXRpb24gd2hlcmUgd2Ugb25seSBoYWQgcHJlZGljdG9yIHZhcmlhYmxlcyAob3IgZmVhdHVyZXMpIHdpdGhvdXQgaGF2aW5nIG9ic2VydmVkIGEgY29ycmVzcG9uZGluZyBtZWFzdXJlbWVudCBvZiBhaXIgcG9sbHV0aW9uLgoKT3VyIGxlYXJuaW5nIG9iamVjdGl2ZXMgd2VyZTogCgotIEludHJvZHVjZSBjb25jZXB0cyBpbiBtYWNoaW5lIGxlYXJuaW5nCi0gRGVtb25zdHJhdGUgaG93IHRvIGJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBtb2RlbCB3aXRoIGB0aWR5bW9kZWxzYAotIERlbW9uc3RyYXRlIGhvdyB0byB2aXN1YWxpemUgZ2VvLXNwYXRpYWwgZGF0YSB1c2luZyBgZ2dwbG90MmAKClVzaW5nIHRoZSBtYWNoaW5lIGxlYXJuaW5nIG1vZGVscyBidWlsdCBpbiB0aGlzIGNhc2Ugc3R1ZHksIHdlIGNvdWxkIG5vdyBleHRlbmQgdGhpcyBtb2RlbCB0byBiZSB1c2VkIHRvIHByZWRpY3QgYWlyIHBvbGx1dGlvbiBsZXZlbHMgaW4gYXJlYXMgd2l0aCBwb29yIG1vbml0b3JpbmcsIHRvIGhlbHAgaWRlbnRpZnkgcmVnaW9ucyB3aGVyZSBwb3B1bGF0aW9ucyBtYXliZSBlc3BlY2lhbGx5IGF0IHJpc2sgZm9yIHRoZSBoZWFsdGggZWZmZWN0cyBvZiBhaXIgcG9sbHV0aW9uLiAgCgpBbmFseXNlcyBsaWtlIHRoZSBvbmUgaW4gb3VyIGNhc2Ugc3R1ZHkgYXJlIGltcG9ydGFudCBmb3IgZGVmaW5pbmcgd2hpY2ggZ3JvdXBzIGNvdWxkIGJlbmVmaXQgdGhlIG1vc3QgZnJvbSBpbnRlcnZlbnRpb25zLCBlZHVjYXRpb24sIGFuZCBwb2xpY3kgY2hhbmdlcyB3aGVuIGF0dGVtcHRpbmcgdG8gbWl0aWdhdGUgcHVibGljIGhlYWx0aCBjaGFsbGVuZ2VzLiBZb3UgY2FuIHNlZSBpbiB0aGlzIFthcnRpY2xlXShodHRwczovL3d3dy5uZWptLm9yZy9kb2kvZnVsbC8xMC4xMDU2L05FSk1vYTE3MDI3NDcpe3RhcmdldD0iX2JsYW5rIn0gdGhhdCBtYW55IGFkZGl0aW9uYWwgY29uc2lkZXJhdGlvbnMgd291bGQgYmUgaW52b2x2ZWQgdG8gYWRlcXVhdGVseSB1bmRlcnN0YW5kIHRoZSBkYXRhIGVub3VnaCB0byByZWNvbW1lbmQgcG9saWN5IGNoYW5nZXMuCgpIZXJlIGFyZSBzb21lIHZpc3VhbCBzdW1tYXJpZXMgYWJvdXQgd2hhdCB3ZSBsZWFybmVkIGFib3V0IHVzaW5nIGB0aWR5bW9kZWxzYCB0byBwZXJmb3JtIHByZWRpY3Rpb24gYW5hbHlzZXMuCgpGaXJzdCB0aGUgbWluaW1hbCBzdGVwcyByZXF1aXJlZDoKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwidGlkeW1vZGVsc0Jhc2ljcy5wbmciKSkKYGBgCgoKSGVyZSBpcyBhIGd1aWRlIGZvciBtb3JlIGFkdmFuY2VkIGFuYWx5c2VzIGludm9sdmluZyBwcmVwcm9jZXNzaW5nLCBjcm9zcyB2YWxpZGF0aW9uLCBvciB0dW5pbmc6CgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsImZ1bGxfdGlkeW1vZGVsc19vdmVydmlldy5wbmciKSkKYGBgCgoKCgo8ZGV0YWlscz48c3VtbWFyeT4gQ2xpY2sgaGVyZSBmb3IgbW9yZSBvbiB3aGF0IHdlIGxlYXJuZWQgd2l0aCBgdGlkeW1vZGVsc2AgPC9zdW1tYXJ5PgoKSGVyZSwgd2UgcHJvdmlkZSBhbiBvdmVydmlldyBvZiB0aGUgYHRpZHltb2RlbHNgIGZyYW1ld29yay4gCgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsImVjb3N5c3RlbS5wbmciKSkKYGBgCgoKV2UgcGVyZm9ybWVkIHRoZSBtYWpvciBzdGVwcyBvZiBtYWNoaW5lIGxlYXJuaW5nIHRoYXQgd2UgaW50cm9kdWNlZCBpbiB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkYXRhIGFuYWx5c2lzOiAgCgoxLiBEYXRhIGV4cGxvcmF0aW9uICAKCldlIHVzZWQgcGFja2FnZXMgbGlrZSBgc2tpbXJgLCBgc3VtbWFyeXRvb2xzYCwgYGNvcnJwbG90YCwgYW5kIGBHR2FsbHlgIHRvIGJldHRlciB1bmRlcnN0YW5kIG91ciBkYXRhLiBUaGVzZSBwYWNrYWdlcyBjYW4gdGVsbCB1cyBob3cgbWFueSBtaXNzaW5nIHZhbHVlcyBlYWNoIHZhcmlhYmxlIGhhcyAoaWYgYW55KSwgdGhlIGNsYXNzIG9mIGVhY2ggdmFyaWFibGUsIHRoZSBkaXN0cmlidXRpb24gb2YgdmFsdWVzIGZvciBlYWNoIHZhcmlhYmxlLCB0aGUgc3BhcnNpdHkgb2YgZWFjaCB2YXJpYWJsZSwgYW5kIHRoZSBsZXZlbCBvZiBjb3JyZWxhdGlvbiBiZXR3ZWVuIHZhcmlhYmxlcy4gIAoKMi4gRGF0YSBzcGxpdHRpbmcgCgpXZSB1c2VkIHRoZSBgcnNhbXBsZWAgcGFja2FnZSB0byBmaXJzdCBwZXJmb3JtIGFuIGluaXRpYWwgc3BsaXQgb2Ygb3VyIGRhdGEgaW50byB0d28gcGllY2VzOiBhIHRyYWluaW5nIHNldCBhbmQgYSB0ZXN0aW5nIHNldC4gVGhlIHRyYWluaW5nIHNldCB3YXMgdXNlZCB0byBvcHRpbWl6ZSB0aGUgbW9kZWwsIHdoaWxlIHRoZSB0ZXN0aW5nIHNldCB3YXMgdXNlZCBvbmx5IHRvIGV2YWx1YXRlIHRoZSBwZXJmb3JtYW5jZSBvZiBvdXIgZmluYWwgbW9kZWwuIFdlIGFsc28gdXNlZCB0aGUgYHJzYW1wbGVgIHBhY2thZ2UgdG8gY3JlYXRlIGNyb3NzIHZhbGlkYXRpb24gc3Vic2V0cyBvZiBvdXIgdHJhaW5pbmcgZGF0YS4gVGhpcyBhbGxvd2VkIHVzIHRvIGJldHRlciBhc3Nlc3MgdGhlIHBlcmZvcm1hbmNlIG9mIG91ciB0ZXN0ZWQgbW9kZWxzIHVzaW5nIG91ciB0cmFpbmluZyBkYXRhLiAgCgozLiBWYXJpYWJsZSBhc3NpZ25tZW50IGFuZCBwcmUtcHJvY2Vzc2luZyAgIAoKV2UgdXNlZCB0aGUgYHJlY2lwZXNgIHBhY2thZ2UgdG8gYXNzaWduIHZhcmlhYmxlIHJvbGVzIChzdWNoIGFzIG91dGNvbWUsIHByZWRpY3RvciwgYW5kIGlkIHZhcmlhYmxlKS4gV2UgYWxzbyB1c2VkIHRoaXMgcGFja2FnZSB0byBjcmVhdGUgYSByZWNpcGUgZm9yIHByZS1wcm9jZXNzaW5nIG91ciB0cmFpbmluZyBhbmQgdGVzdGluZyBkYXRhLiBUaGlzIGludm9sdmVkIHN0ZXBzIHN1Y2ggYXM6IGAgc3RlcF9kdW1teWAgdG8gY3JlYXRlIGR1bW15IG51bWVyaWMgZW5jb2RpbmdzIG9mIG91ciBjYXRlZ29yaWNhbCB2YXJpYWJsZXMsIGBzdGVwX2NvcnJgIHRvIHJlbW92ZSBoaWdobHkgY29ycmVsYXRlZCB2YXJpYWJsZXMsIGBzdGVwX256dmAgdG8gcmVtb3ZlIG5lYXIgemVybyB2YXJpYW5jZSB2YXJpYWJsZXMgdGhhdCB3b3VsZCBjb250cmlidXRlIGxpdHRsZSB0byBvdXIgbW9kZWwgYW5kIHBvdGVudGlhbGx5IGFkZCBub2lzZS4gIFdlIGxlYXJuZWQgdGhhdCBvbmNlIG91ciByZWNpcGUgd2FzIGNyZWF0ZWQgYW5kIHByZXBwZWQgdXNpbmcgYHByZXAoKWB3ZSBjb3VsZCBleHRyYWN0IHRoZSBwcmUtcHJvY2Vzc2VkIHRyYWluaW5nIGRhdGEgb3Igb3VyIHByZS1wcm9jZXNzZWQgdGVzdGluZyBkYXRhIHVzaW5nIGBiYWtlKClgLiBXZSBhbHNvIGxlYXJuZWQgdGhhdCBpZiB3ZSB1c2VkIHRoZSBuZXdlciB3b3JrZmxvd3MgcGFja2FnZSB0aGF0IHdlIGRpZCBub3QgbmVlZCB0byB1c2UgdGhlIGBwcmVwKClgIG9yIGBiYWtlKClgIGZ1bmN0aW9ucywgYnV0IHRoYXQgaXQgaXMgc3RpbGwgdXNlZnVsIHRvIGtub3cgaG93IHRvIGRvIHNvIGlmIHdlIHdhbnQgdG8gbG9vayBhdCBvdXIgZGF0YSBhbmQgaG93IHRoZSByZWNpcGUgaXMgaW5mbHVlbmNpbmcgaXQgbW9yZSBkZWVwbHkuICAKCjQuIE1vZGVsIHNwZWNpZmljYXRpb24sIGZpdHRpbmcsIHR1bmluZyBhbmQgcGVyZm9ybWFuY2UgZXZhbHVhdGlvbiB1c2luZyB0aGUgdHJhaW5pbmcgZGF0YSAgCgpXZSBsZWFybmVkIHRoYXQgdGhlIG1vZGVsIG5lZWRzIHRvIGZpcnN0IGJlIGZpdCB0byB0aGUgdHJhaW5pbmcgZGF0YS4gV2UgbGVhcm5lZCB0aGF0IGluIGJvdGggY2xhc3NpZmljYXRpb24gYW5kIHByZWRpY3Rpb24sIHRoZSBtb2RlbCBpcyBmaXQgdG8gdGhlIHRyYWluaW5nIGRhdGEgYW5kIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgYXJlIHVzZWQgdG8gZXN0aW1hdGUgbnVtZXJpYyB2YWx1ZXMgKGluIHRoZSBjYXNlIG9mIHByZWRpY3Rpb24pIG9yIGNhdGVnb3JpY2FsIHZhbHVlcyAoaW4gdGhlIGNhc2Ugb2YgY2xhc3NpZmljYXRpb24pIG9mIHRoZSBvdXRjb21lIHZhcmlhYmxlIG9mIGludGVyZXN0LiBXZSBsZWFybmVkIHRoYXQgd2Ugc3BlY2lmeSB0aGUgbW9kZWwgYW5kIGl0cyBzcGVjaWZpY2F0aW9ucyB1c2luZyB0aGUgYHBhcm5zaXBgIHBhY2thZ2UgYW5kIHRoYXQgd2UgYWxzbyB1c2UgdGhpcyBwYWNrYWdlIHRvIGZpdCB0aGUgbW9kZWwgdXNpbmcgdGhlIGBmaXQoKWAgZnVuY3Rpb24uIFdlIGxlYXJuZWQgdGhhdCBpZiB3ZSBqdXN0IHVzZSBgcGFyc25pcGAgdG8gZml0IHRoZSBtb2RlbCwgdGhlbiB3ZSBuZWVkIHRvIHVzZSB0aGUgcHJlLXByb2Nlc3NlZCB0cmFpbmluZyBkYXRhIChvdXRwdXQgZnJvbSBgYmFrZSgpYCkuIFdlIGxlYXJuZWQgdGhhdCB3ZSBjYW4gdXNlIHRoZSByYXcgdHJhaW5pbmcgZGF0YSBpZiB3ZSB1c2UgdGhlIGB3b3JrZmxvd3NgIHBhY2thZ2UgdG8gY3JlYXRlIGEgd29ya2Zsb3cgdGhhdCBwcmUtcHJvY2Vzc2VzIG91ciBkYXRhIGZvciB1cy4gICAKCldlIGxlYXJuZWQgdGhhdCBpZiB0aGUgbW9kZWwgZml0cyB3ZWxsIHRoYW4gdGhlIGVzdGltYXRlZCB2YWx1ZXMgd2lsbCBiZSB2ZXJ5IHNpbWlsYXIgdG8gdGhlIHRydWUgb3V0Y29tZSB2YXJpYWJsZSB2YWx1ZXMgaW4gb3VyIHRyYWluaW5nIGRhdGEuIFdlIGxlYXJuZWQgdGhhdCB3ZSBjYW4gYXNzZXNzIG1vZGVsIHBlcmZvcm1hbmNlIHVzaW5nIHRoZSBgeWFyZHN0aWNrYCBwYWNrYWdlIHdpdGggdGhlIGBtZXRyaWNzYCBmdW5jdGlvIG9yIHRoZSBgdHVuZWAgcGFja2FnZSBhbmQgdGhlIGBjb2xsZWN0X21ldHJpY3MoKWAgZnVuY3Rpb24gKHJlcXVpcmVkIGlmIHVzaW5nIGNyb3NzIHZhbGlkYXRpb24gb3IgdHVuaW5nKS4gV2UgYWxzbyBsZWFybmVkIHRoYXQgd2UgY2FuIHVzZSBzdWJzZXRzIG9mIG91ciB0cmFpbmluZyBkYXRhICh3aGljaCB3ZSBjcmVhdGVkIHdpdGggdGhlIGByc2FtcGxlYCBwYWNrYWdlKSB0byBwZXJmb3JtIGNyb3NzIHZhbGlkYXRpb24gdG8gZ2V0IGEgYmV0dGVyIGVzdGltYXRlIGFib3V0IHRoZSBwZXJmb3JtYW5jZSBvZiBvdXIgbW9kZWwgdXNpbmcgb3VyIHRyYWluaW5nIGRhdGEsIGFzIHdlIHdhbnQgb3VyIHJlc3VsdHMgdG8gYmUgZ2VuZXJhbGl6YWJsZSBhbmQgdG8gcGVyZm9ybSB3ZWxsIHdpdGggb3RoZXIgZGF0YSwgbm90IGp1c3Qgb3VyIHRyYWluaW5nIGRhdGEuIFdlIHVzZWQgdGhlIGBmaXRfcmVzYW1wbGVzKClgIGZ1bmN0aW9uIG9mIHRoZSB0dW5lIHBhY2thZ2UgdG8gZml0IG91ciBtb2RlbCBvbiBvdXIgZGlmZmVyZW50IHRyYWluaW5nIGRhdGEgc3Vic2V0cyBhbmQgdGhlIGBjb2xsZWN0X21ldHJpY3MoKWAgZnVuY3Rpb24gKGFsc28gb2YgdGhlIGB0dW5lYCBwYWNrYWdlKSB0byBldmFsdWF0ZSBtb2RlbCBwZXJmb3JtYW5jZSB1c2luZyB0aGVzZSBzdWJzZXRzLiAgV2UgYWxzbyBsZWFybmVkIHRoYXQgd2UgY2FuIHBvdGVudGlhbGx5IGltcHJvdmUgbW9kZWwgcGVyZm9ybWFuY2UgYnkgdHVuaW5nIGFzcGVjdHMgYWJvdXQgdGhlIG1vZGVsIGNhbGxlZCBbaHlwZXJwYXJhbWV0ZXJzXShodHRwczovL21hY2hpbmVsZWFybmluZ21hc3RlcnkuY29tL2RpZmZlcmVuY2UtYmV0d2Vlbi1hLXBhcmFtZXRlci1hbmQtYS1oeXBlcnBhcmFtZXRlci8pe3RhcmdldD0iX2JsYW5rIn0gdG8gZGV0ZXJtaW5lIHRoZSBiZXN0IG9wdGlvbiBmb3IgbW9kZWwgcGVyZm9ybWFuY2UuIFdlIGxlYXJuZWQgdGhhdCB3ZSBjYW4gZG8gdGhpcyB1c2luZyB0aGUgYHR1bmVgIGFuZCBgZGlhbHNgIHBhY2thZ2VzIGFuZCBldmFsdWF0aW5nIHRoZSBwZXJmb3JtYW5jZSBvZiBvdXIgbW9kZWwgd2l0aCB0aGUgZGlmZmVyZW50IGh5cGVycGFyYW1ldGVyIG9wdGlvbnMgYW5kIG91ciB0cmFpbmluZyBkYXRhIHN1YnNldHMgdGhhdCB3ZSB1c2VkIGZvciBjcm9zcyB2YWxpZGF0aW9uLiBBZnRlciB3ZSB0ZXN0ZWQgc2V2ZXJhbCBkaWZmZXJlbnQgbWV0aG9kcyB0byBtb2RlbCBvdXIgZGF0YSwgd2UgY29tcGFyZWQgdGhlbSB0byBjaG9vc2UgdGhlIGJlc3QgcGVyZm9ybWluZyBtb2RlbCBhcyBvdXIgZmluYWwgbW9kZWwuICAKCgo1LiBPdmVyYWxsIG1vZGVsIHBlcmZvcm1hbmNlIGV2YWx1YXRpb24gIAoKT25jZSB3ZSBjaG9zZSBvdXIgZmluYWwgbW9kZWwsIHdlIGV2YWx1YXRlZCB0aGUgZmluYWwgbW9kZWwgcGVyZm9ybWFuY2UgdXNpbmcgdGhlIHRlc3RpbmcgZGF0YSB1c2luZyB0aGUgYGxhc3RfZml0KClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZWAgcGFja2FnZS4gVGhpcyBnaXZlcyB1cyBhIGJldHRlciBlc3RpbWF0ZSBhYm91dCBob3cgd2VsbCB0aGUgbW9kZWwgd2lsbCBwcmVkaWN0IG9yIGNsYXNzaWZ5IHRoZSBvdXRjb21lIHZhcmlhYmxlIG9mIGludGVyZXN0IHdpdGggbmV3IGluZGVwZW5kZW50IGRhdGEuIElkZWFsbHkgb25lIHdvdWxkIGFsc28gcGVyZm9ybSBhbiBldmFsdWF0aW9uIHdpdGggaW5kZXBlbmRlbnQgZGF0YSB0byBwcm92aWRlIGEgc2Vuc2Ugb2YgaG93IGdlbmVyYWxpemFibGUgdGhlIG1vZGVsIGlzIHRvIG90aGVyIGRhdGEgc291cmNlcy4gCgpXZSBhbHNvIHNhdyB0aGF0IHdlIGNhbiB1c2UgdGhlIGBjb2xsZWN0X3ByZWRpY3Rpb25zKClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZWAgcGFja2FnZSB0byBnZXQgdGhlIHByZWRpY3Rpb25zIGZvciBvdXIgdGVzdCBkYXRhLiBXZSBzYXcgdGhhdCB3ZSBjYW4gZ2V0IG1vcmUgZGV0YWlsZWQgcHJlZGljdGlvbiBkYXRhIHVzaW5nIHRoZSBgcHJlZGljdCgpYCBmdW5jdGlvbiBvZiB0aGUgYHBhcnNuaXBgIHBhY2thZ2UuCgo8L2RldGFpbHM+CgoKCiMjICoqU3VnZ2VzdGVkIEhvbWV3b3JrKioKKioqCgpTdHVkZW50cyBjYW4gcHJlZGljdCBhaXIgcG9sbHV0aW9uIG1vbml0b3IgdmFsdWVzIHVzaW5nIGEgZGlmZmVyZW50IGFsZ29yaXRobSBhbmQgcHJvdmlkZSBhbiBleHBsYW5hdGlvbiBmb3IgaG93IHRoYXQgYWxnb3JpdGhtIHdvcmtzIGFuZCB3aHkgaXQgbWF5IGJlIGEgZ29vZCBjaG9pY2UgZm9yIG1vZGVsaW5nIHRoaXMgZGF0YS4KCgojICoqQWRkaXRpb25hbCBJbmZvcm1hdGlvbioqCioqKgoKIyMgKipIZWxwZnVsIExpbmtzKioKKioqCgoxLiBBIHJldmlldyBvZiBbdGlkeW1vZGVsc10oaHR0cHM6Ly9ydmlld3MucnN0dWRpby5jb20vMjAxOS8wNi8xOS9hLWdlbnRsZS1pbnRyby10by10aWR5bW9kZWxzLyl7dGFyZ2V0PSJfYmxhbmsifSAgCjIuIEEgW2NvdXJzZSBvbiB0aWR5bW9kZWxzXShodHRwczovL2p1bGlhc2lsZ2UuY29tL2Jsb2cvdGlkeW1vZGVscy1tbC1jb3Vyc2UvKXt0YXJnZXQ9Il9ibGFuayJ9IGJ5IEp1bGlhIFNpbGdlICAKMy4gW01vcmUgZXhhbXBsZXMsIGV4cGxhbmF0aW9ucywgYW5kIGluZm8gYWJvdXQgdGlkeW1vZGVscyBkZXZlbG9wbWVudF0oaHR0cHM6Ly93d3cudGlkeW1vZGVscy5vcmcvbGVhcm4vKXt0YXJnZXQ9Il9ibGFuayJ9IGZyb20gdGhlIGRldmVsb3BlcnMgIAo0LiBBIGd1aWRlIGZvciBbcHJlLXByb2Nlc3Npbmcgd2l0aCByZWNpcGVzXShodHRwOi8vd3d3LnJlYmVjY2FiYXJ0ZXIuY29tL2Jsb2cvMjAxOS0wNi0wNl9wcmVfcHJvY2Vzc2luZy8pe3RhcmdldD0iX2JsYW5rIn0gIAo1LiBBIFtndWlkZV0oaHR0cHM6Ly9icmlhdHRlLmdpdGh1Yi5pby9nZ2NvcnIvKXt0YXJnZXQ9Il9ibGFuayJ9IGZvciB1c2luZyBHR2FsbHkgdG8gY3JlYXRlIGNvcnJlbGF0aW9uIHBsb3RzICAKNi4gQSBbZ3VpZGVdKGh0dHBzOi8vd3d3LnRpZHl2ZXJzZS5vcmcvYmxvZy8yMDE4LzExL3BhcnNuaXAtMC0wLTEvKXt0YXJnZXQ9Il9ibGFuayJ9IGZvciB1c2luZyBwYXJzbmlwIHRvIHRyeSBkaWZmZXJlbnQgYWxnb3JpdGhtcyBvciBlbmdpbmVzICAKNy4gQSBbbGlzdCBvZiByZWNpcGUgZnVuY3Rpb25zXShodHRwczovL3RpZHltb2RlbHMuZ2l0aHViLmlvL3JlY2lwZXMvcmVmZXJlbmNlL2luZGV4Lmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gIAo4LiBBIGdyZWF0IGJsb2cgcG9zdCBhYm91dCBbY3Jvc3MgdmFsaWRhdGlvbl0oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3RyYWluLXRlc3Qtc3BsaXQtYW5kLWNyb3NzLXZhbGlkYXRpb24taW4tcHl0aG9uLTgwYjYxYmVjYTRiNil7dGFyZ2V0PSJfYmxhbmsifSAgCjkuIEEgZGlzY3Vzc2lvbiBhYm91dCBbZXZhbHVhdGluZyBtb2RlbCBwZXJmb3JtYW5jZV0oaHR0cHM6Ly9tZWRpdW0uY29tL0BsaW1hdmFsbGFudGluL21ldHJpY3MtdG8tbWVhc3VyZS1tYWNoaW5lLWxlYXJuaW5nLW1vZGVsLXBlcmZvcm1hbmNlLWU4Yzk2MzY2NTQ3Nil7dGFyZ2V0PSJfYmxhbmsifSBmb3IgYSBkZWVwZXIgZXhwbGFuYXRpb24gYWJvdXQgaG93IHRvIGV2YWx1YXRlIG1vZGVsIHBlcmZvcm1hbmNlICAKMTAuIFtSU3R1ZGlvIGNoZWF0c2hlZXRzXShodHRwczovL3JzdHVkaW8uY29tL3Jlc291cmNlcy9jaGVhdHNoZWV0cy8pe3RhcmdldD0iX2JsYW5rIn0KMTEuIEFuIFtleHBsYW5hdGlvbl0oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3N1cGVydmlzZWQtdnMtdW5zdXBlcnZpc2VkLWxlYXJuaW5nLTE0ZjY4ZTMyZWE4ZCl7dGFyZ2V0PSJfYmxhbmsifSBvZiBzdXBlcnZpc2VkIHZzIHVuc3VwZXJ2aXNlZCBtYWNoaW5lIGxlYXJuaW5nIGFuZCBiaWFzLXZhcmlhbmNlIHRyYWRlLW9mZi4KMTIuIEEgdGhvcm91Z2ggW2V4cGxhbmF0aW9uXShodHRwczovL3JveWFsc29jaWV0eXB1Ymxpc2hpbmcub3JnL2RvaS8xMC4xMDk4L3JzdGEuMjAxNS4wMjAyIzp+OnRleHQ9UHJpbmNpcGFsJTIwY29tcG9uZW50JTIwYW5hbHlzaXMlMjAoUENBKSUyMGlzLHZhcmlhYmxlcyUyMHRoYXQlMjBzdWNjZXNzaXZlbHklMjBtYXhpbWl6ZSUyMHZhcmlhbmNlLil7dGFyZ2V0PSJfYmxhbmsifSBvZiBwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzLgoxMy4gSWYgeW91IGhhdmUgYWNjZXNzLCB0aGlzIGlzIGEgZ3JlYXQgW2Rpc2N1c3Npb25dKGh0dHBzOi8vd3d3LnRhbmRmb25saW5lLmNvbS9kb2kvYWJzLzEwLjEwODAvMDAwMzEzMDUuMTk4NC4xMDQ4MzE4Myl7dGFyZ2V0PSJfYmxhbmsifSAgYWJvdXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBpbmRlcGVuZGVuY2UsIG9ydGhvZ29uYWxpdHksIGFuZCBsYWNrIG9mIGNvcnJlbGF0aW9uLgoxNC4gR3JlYXQgW3ZpZGVvIGV4cGxhbmF0aW9uXShodHRwczovL3lvdXR1LmJlL19VVkhuZUJVQlcwKXt0YXJnZXQ9Il9ibGFuayJ9IG9mIFBDQS4gIAoKPHU+VGVybXMgYW5kIGNvbmNlcHRzIGNvdmVyZWQ6PC91PiAgCgpbVGlkeXZlcnNlXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgCltJbXB1dGF0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JbXB1dGF0aW9uXyhzdGF0aXN0aWNzKSl7dGFyZ2V0PSJfYmxhbmsifSAgCltUcmFuc2Zvcm1hdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRGF0YV90cmFuc2Zvcm1hdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gIApbRGlzY3JldGl6YXRpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Rpc2NyZXRpemF0aW9uX29mX2NvbnRpbnVvdXNfZmVhdHVyZXMpe3RhcmdldD0iX2JsYW5rIn0gIApbRHVtbXkgVmFyaWFibGVzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EdW1teV92YXJpYWJsZV8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gIApbT25lIEhvdCBFbmNvZGluZ10oaHR0cHM6Ly9tYWNoaW5lbGVhcm5pbmdtYXN0ZXJ5LmNvbS93aHktb25lLWhvdC1lbmNvZGUtZGF0YS1pbi1tYWNoaW5lLWxlYXJuaW5nLyl7dGFyZ2V0PSJfYmxhbmsifSAgCltEYXRhIFR5cGUgQ29udmVyc2lvbnNdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9oYWJsYXIvdmlnbmV0dGVzL2NvbnZlcnQuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgCltJbnRlcmFjdGlvbl0oaHR0cHM6Ly9zdGF0aXN0aWNzYnlqaW0uY29tL3JlZ3Jlc3Npb24vaW50ZXJhY3Rpb24tZWZmZWN0cy8pe3RhcmdldD0iX2JsYW5rIn0gIApbTm9ybWFsaXphdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTm9ybWFsaXphdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gIApbRGltZW5zaW9uYWxpdHkgUmVkdWN0aW9uL1NpZ25hbCBFeHRyYWN0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EaW1lbnNpb25hbGl0eV9yZWR1Y3Rpb24pe3RhcmdldD0iX2JsYW5rIn0gIApbUm93IE9wZXJhdGlvbnNdKGh0dHBzOi8vdGFydGFydXMub3JnL2dhcmV0aC9tYXRocy9MaW5lYXJfQWxnZWJyYS9yb3dfb3BlcmF0aW9ucy5wZGYpe3RhcmdldD0iX2JsYW5rIn0gIApbTmVhciBaZXJvIFZhcmFpbmNlXShodHRwczovL3d3dy5yLWJsb2dnZXJzLmNvbS9uZWFyLXplcm8tdmFyaWFuY2UtcHJlZGljdG9ycy1zaG91bGQtd2UtcmVtb3ZlLXRoZW0vKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW1BhcmFtZXRlcnMgYW5kIEh5cGVycGFyYW1ldGVyc10oaHR0cHM6Ly9tYWNoaW5lbGVhcm5pbmdtYXN0ZXJ5LmNvbS9kaWZmZXJlbmNlLWJldHdlZW4tYS1wYXJhbWV0ZXItYW5kLWEtaHlwZXJwYXJhbWV0ZXIvKXt0YXJnZXQ9Il9ibGFuayJ9ICAgCltTdXBlcnZpc2VkIGFuZCBVbnNwZXJ2aXNlZCBMZWFybmluZ10oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3N1cGVydmlzZWQtdnMtdW5zdXBlcnZpc2VkLWxlYXJuaW5nLTE0ZjY4ZTMyZWE4ZCl7dGFyZ2V0PSJfYmxhbmsifSAgCltQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzXShodHRwczovL21lZGl1bS5jb20vQHNhdmFzdGFtaXJrby9wY2EtYS1saW5lYXItdHJhbnNmb3JtYXRpb24tZjhhYWNkNGViMDA3KXt0YXJnZXQ9Il9ibGFuayJ9ICAKW0xpbmVhciBDb21iaW5hdGlvbnNdKGh0dHBzOi8vd3d3Lm1hdGhib290Y2FtcHMuY29tL2xpbmVhci1jb21iaW5hdGlvbnMtdmVjdG9ycy8pe3RhcmdldD0iX2JsYW5rIn0gIApbRGVjaXNpb24gVHJlZV0oaHR0cHM6Ly9tZWRpdW0uY29tL2dyZXlhdG9tL2RlY2lzaW9uLXRyZWVzLWEtc2ltcGxlLXdheS10by12aXN1YWxpemUtYS1kZWNpc2lvbi1kYzUwNmE0MDNhZWIpe3RhcmdldD0iX2JsYW5rIn0gIApbUmFuZG9tIEZvcmVzdF0oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL2RlY2lzaW9uLXRyZWUtZW5zZW1ibGVzLWJhZ2dpbmctYW5kLWJvb3N0aW5nLTI2NmE4YmE2MGZkOSl7dGFyZ2V0PSJfYmxhbmsifSAgCgoKIDx1PioqUGFja2FnZXMgdXNlZCBpbiB0aGlzIGNhc2Ugc3R1ZHk6KiogPC91PgoKUGFja2FnZSAgIHwgVXNlIGluIHRoaXMgY2FzZSBzdHVkeSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLS0tLS0tLS0tLSB8LS0tLS0tLS0tLS0tLQpbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL2plbm55YmMvaGVyZV9oZXJlKXt0YXJnZXQ9Il9ibGFuayJ9ICAgICAgIHwgdG8gZWFzaWx5IGxvYWQgYW5kIHNhdmUgZGF0YQpbcmVhZHJdKGh0dHBzOi8vcmVhZHIudGlkeXZlcnNlLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gICAgICB8IHRvIGltcG9ydCB0aGUgQ1NWIGZpbGUgZGF0YQpbZHBseXJdKGh0dHBzOi8vZHBseXIudGlkeXZlcnNlLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gICAgICB8IHRvIHZpZXcvYXJyYW5nZS9maWx0ZXIvc2VsZWN0L2NvbXBhcmUgc3BlY2lmaWMgc3Vic2V0cyBvZiB0aGUgZGF0YSAKW3NraW1yXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvc2tpbXIvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gZ2V0IGFuIG92ZXJ2aWV3IG9mIGRhdGEKW3N1bW1hcnl0b29sc10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3NraW1yL2luZGV4Lmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gICAgICB8IHRvIGdldCBhbiBvdmVydmlldyBvZiBkYXRhIGluIGEgZGlmZmVyZW50IHN0eWxlClttYWdyaXR0cl0oaHR0cHM6Ly9tYWdyaXR0ci50aWR5dmVyc2Uub3JnL2FydGljbGVzL21hZ3JpdHRyLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gICB8IHRvIHVzZSB0aGUgYCU8PiVgIHBpcHBpbmcgb3BlcmF0b3IgCltjb3JycGxvdF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2NvcnJwbG90L3ZpZ25ldHRlcy9jb3JycGxvdC1pbnRyby5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gbWFrZSBsYXJnZSBjb3JyZWxhdGlvbiBwbG90cwpbR0dhbGx5XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvR0dhbGx5L0dHYWxseS5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBtYWtlIHNtYWxsZXIgY29ycmVsYXRpb24gcGxvdHMgIApbcnNhbXBsZV0oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby9yc2FtcGxlL2FydGljbGVzL0Jhc2ljcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAgfCB0byBzcGxpdCB0aGUgZGF0YSBpbnRvIHRlc3RpbmcgYW5kIHRyYWluaW5nIHNldHMgYW5kIHRvIHNwbGl0IHRoZSB0cmFpbmluZyBzZXQgZm9yIGNyb3NzLXZhbGlkYXRpb24gIApbcmVjaXBlc10oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby9yZWNpcGVzLyl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgdG8gcHJlLXByb2Nlc3MgZGF0YSBmb3IgbW9kZWxpbmcgaW4gYSB0aWR5IGFuZCByZXByb2R1Y2libGUgd2F5IGFuZCB0byBleHRyYWN0IHByZS1wcm9jZXNzZWQgZGF0YSAobWFqb3IgZnVuY3Rpb25zIGFyZSBgcmVjaXBlKClgICwgYHByZXAoKWAgYW5kIHZhcmlvdXMgdHJhbnNmb3JtYXRpb24gYHN0ZXBfKigpYCBmdW5jdGlvbnMsIGFzIHdlbGwgYXMgYGJha2VgIHdoaWNoIGV4dHJhY3RzIHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YSAodXNlZCB0byByZXF1aXJlIGBqdWljZSgpYCkgYW5kIGFwcGxpZXMgcmVjaXBlIHByZXByb2Nlc3Npbmcgc3RlcHMgdG8gdGVzdGluZyBkYXRhKS4gU2VlIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmVjaXBlcy9yZWNpcGVzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSAgZm9yIG1vcmUgaW5mby4KW3BhcnNuaXBdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcGFyc25pcC8pe3RhcmdldD0iX2JsYW5rIn0gICB8IGFuIGludGVyZmFjZSB0byBjcmVhdGUgbW9kZWxzIChtYWpvciBmdW5jdGlvbnMgYXJlICBgZml0KClgLCBgc2V0X2VuZ2luZSgpYCkKW3lhcmRzdGlja10oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby95YXJkc3RpY2svKXt0YXJnZXQ9Il9ibGFuayJ9ICAgfCB0byBldmFsdWF0ZSB0aGUgcGVyZm9ybWFuY2Ugb2YgbW9kZWxzClticm9vbV0oaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZy9ibG9nLzIwMTgvMDcvYnJvb20tMC01LTAvKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gZ2V0IHRpZHkgb3V0cHV0IGZvciBvdXIgbW9kZWwgZml0IGFuZCBwZXJmb3JtYW5jZQpbZ2dwbG90Ml0oaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvKXt0YXJnZXQ9Il9ibGFuayJ9ICAgIHwgdG8gbWFrZSB2aXN1YWxpemF0aW9ucyB3aXRoIG11bHRpcGxlIGxheWVycwpbZGlhbHNdKGh0dHBzOi8vd3d3LnRpZHl2ZXJzZS5vcmcvYmxvZy8yMDE5LzEwL2RpYWxzLTAtMC0zLyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHNwZWNpZnkgaHlwZXItcGFyYW1ldGVyIHR1bmluZwpbdHVuZV0oaHR0cHM6Ly90dW5lLnRpZHltb2RlbHMub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHBlcmZvcm0gY3Jvc3MgdmFsaWRhdGlvbiwgdHVuZSBoeXBlci1wYXJhbWV0ZXJzLCBhbmQgZ2V0IHBlcmZvcm1hbmNlIG1ldHJpY3MKW3dvcmtmbG93c10oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3dvcmtmbG93cy92ZXJzaW9ucy8wLjEuMSl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGNyZWF0ZSBtb2RlbGluZyB3b3JrZmxvdyB0byBzdHJlYW1saW5lIHRoZSBtb2RlbGluZyBwcm9jZXNzClt2aXBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy92aXAvdmlwLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGNyZWF0ZSB2YXJpYWJsZSBpbXBvcnRhbmNlIHBsb3RzCltyYW5kb21Gb3Jlc3RdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yYW5kb21Gb3Jlc3QvcmFuZG9tRm9yZXN0LnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHBlcmZvcm0gdGhlIHJhbmRvbSBmb3Jlc3QgYW5hbHlzaXMKW2RvUGFyYWxsZWxdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9kb1BhcmFsbGVsL2RvUGFyYWxsZWwucGRmKSB8IHRvIGZpdCBjcm9zcyB2YWxpZGF0aW9uIHNhbXBsZXMgaW4gcGFyYWxsZWwgCltzdHJpbmdyXShodHRwczovL3N0cmluZ3IudGlkeXZlcnNlLm9yZy9hcnRpY2xlcy9zdHJpbmdyLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gICAgfCB0byBtYW5pcHVsYXRlIHRoZSB0ZXh0IHRoZSBtYXAgZGF0YQpbdGlkeXJdKGh0dHBzOi8vdGlkeXIudGlkeXZlcnNlLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gICAgICB8IHRvIHNlcGFyYXRlIGRhdGEgd2l0aGluIGEgY29sdW1uIGludG8gbXVsdGlwbGUgY29sdW1ucwpbcm5hdHVyYWxlYXJ0aF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3JuYXR1cmFsZWFydGgvUkVBRE1FLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBnZXQgdGhlIGdlb21ldHJ5IGRhdGEgZm9yIHRoZSBlYXJ0aCB0byBwbG90IHRoZSBVUwpbbWFwc10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL21hcHMvbWFwcy5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBnZXQgbWFwIGRhdGFiYXNlIGRhdGEgYWJvdXQgY291bnRpZXMgdG8gZHJhdyB0aGVtIG9uIG91ciBVUyBtYXAKW3NmXShodHRwczovL3Itc3BhdGlhbC5naXRodWIuaW8vc2YvKXt0YXJnZXQ9Il9ibGFuayJ9ICB8IHRvIGNvbnZlcnQgdGhlIG1hcCBkYXRhIGludG8gYSBkYXRhIGZyYW1lCltsd2dlb21dKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9sd2dlb20vbHdnZW9tLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHVzZSB0aGUgYHNmYCBmdW5jdGlvbiB0byBjb252ZXJ0IHRoZSBtYXAgZ2VvZ3JhcGhpY2FsIGRhdGEKW3JnZW9zXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmdlb3Mvcmdlb3MucGRmKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gdXNlIGdlb21ldHJ5IGRhdGEKW3BhdGNod29ya10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3BhdGNod29yay9wYXRjaHdvcmsucGRmKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gYWxsb3cgcGxvdHMgdG8gYmUgY29tYmluZWQKCgojIyAqKlNlc3Npb24gaW5mbyoqCioqKgoKCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoKCiMjICoqQWNrbm93bGVkZ2VtZW50cyoqCioqKgoKCldlIHdvdWxkIGxpa2UgdG8gYWNrbm93bGVkZ2UgW1JvZ2VyIFBlbmddKGh0dHA6Ly93d3cuYmlvc3RhdC5qaHNwaC5lZHUvfnJwZW5nLyksIFtNZWdhbiBMYXRzaGF3XShodHRwczovL3d3dy5qaHNwaC5lZHUvZmFjdWx0eS9kaXJlY3RvcnkvcHJvZmlsZS8xNzA4L21lZ2FuLXdlaWwtbGF0c2hhdyksIGFuZCBbS2lyc3RlbiBLb2VobGVyXShodHRwczovL3d3dy5qaHNwaC5lZHUvZmFjdWx0eS9kaXJlY3RvcnkvcHJvZmlsZS8yOTI4L2tpcnN0ZW4ta29laGxlcikgZm9yIGFzc2lzdGluZyBpbiBmcmFtaW5nIHRoZSBtYWpvciBkaXJlY3Rpb24gb2YgdGhlIGNhc2Ugc3R1ZHkuCgpXZSB3b3VsZCBhbHNvIGxpa2UgdG8gYWNrbm93bGVkZ2UgdGhlIFtCbG9vbWJlcmcgQW1lcmljYW4gSGVhbHRoIEluaXRpYXRpdmVdKGh0dHBzOi8vYW1lcmljYW5oZWFsdGguamh1LmVkdS8pIGZvciBmdW5kaW5nIHRoaXMgd29yay4gCg==